仅仅只会Ajax,那就out了!WebSocket实战解锁实时通信新境界!

websocket序言

WebSocket啊,简单来说,就像是一条永远不打烊的"高速通道",让服务器和客户端能够随时随地"煲电话粥"。有了它,服务器再也不用等着客户端来敲门了,可以主动发起聊天,告诉客户端:"嘿,我这里有新消息要告诉你!"而客户端呢,也可以随时回应:"收到啦,谢谢!"

这条"高速通道"不仅速度快,还特别节省流量。想想看,传统的Ajax/HTTP请求每次都要"敲门""问好""报身份",多费劲啊!而WebSocket呢,一旦建立了连接,就像打开了"免提",大家都可以畅所欲言,不用每次都重复那些客套话了。

那么我们应该如何打开websocket的第一扇门呢?

从上篇文章 WebSocket: 实时通信的魔法快递,让你的网络生活飞跃升级!

已经提及

WebSocket 复用了 HTTP 的握手通道,要建立 WebSocket 通信,需要在连接发起方的 HTTP 请求报文中通过 Upgrade 字段告知服务器通信协议升级到 Websocket,然后通过 Sec-WebSocket-* 扩展字段提供 WebSocket 的协议、版本、键值等信息 , 而服务器会返回 101 Switching Protocols 响应表示协议升级成功

简单的,可以用下图理解下流程:

sequenceDiagram participant C as 客户端 participant S as 服务器 C->>S: 发起WebSocket升级的HTTP请求 S-->>C: 返回状态码101 Switching Protocols的HTTP响应 S-->>C: WebSocket握手完成 C-->>S: 发送WebSocket数据(文本/二进制) S-->>C: 发送WebSocket数据(文本/二进制) C-->>S: 发起WebSocket连接关闭请求 S-->>C: WebSocket连接已关闭

WebSocket 真是个聪明的家伙!它巧妙地借用了 HTTP 协议来完成初次握手,然后借助神奇的 Upgrade 字段,成功地把HTTP协议升级成了 WebSocket 协议,建立起一个持久的长连接。一旦这个连接建立起来,客户端和服务端就能随时随地通过 WebSocket 数据帧进行愉快的双向沟通啦!这意味着,不管是客户端还是服务端,都可以随时给对方发送信息,不再像HTTP协议那样,非得等客户端先开口,服务端才能回应。这种灵活的通信方式,完美解决了Web页面实时更新资源的大难题.

实战Demo

在本篇分享中,我将在服务端基于 Node 实现简单的 WebSocket 服务器,然后在客户端基于 JavaScript 实现 WebSocket 客户端,通过这个简单的实现, 加深大家对 WebSocket 通信过程的理解。希望能帮到大家谢谢,给点个小赞。

WebSocket 服务器

代码:

创建一个名为node.js的文件,并输入以下代码:

JS 复制代码
const WebSocket = require('ws')

// 创建WebSocket服务器监听端口3000
const wss = new WebSocket.Server({ port: 3000 })

wss.on('connection', function connection(ws) {
  // 当客户端连接时,打印连接
  console.log('connected')

  // 当接收到客户端消息时,打印消息内容并将其发送回客户端
  ws.on('message', function incoming(message) {
    console.log('received: %s', message)
    ws.send('echo: ' + message)
  })

  // 当连接关闭时,打印信息
  ws.on('close', function close() {
    console.log('disconnected')
  })

  ws.send('Welcome to the WebSocket server!')

  // 发送欢迎消息给客户端
  // setInterval(function () {
  //   ws.send('Welcome to the WebSocket server!')
  // }, 3000)
})
console.log('WebSocket server is running on ws://localhost:3000')

解读:

  1. 引入 ws
javascript 复制代码
const WebSocket = require('ws')

这行代码导入了 ws 库,该库为 Node.js 提供了 WebSocket 服务器的实现。

  1. 创建 WebSocket 服务器
javascript 复制代码
const wss = new WebSocket.Server({ port: 3000 })

这行代码创建了一个新的 WebSocket 服务器实例,并监听 3000 端口。当客户端连接到此端口时,WebSocket 服务器将与其建立连接。

  1. 监听 connection 事件
javascript 复制代码
wss.on('connection', function connection(ws) {
  // ...
})

每当有新的 WebSocket 客户端连接到服务器时,connection 事件都会被触发。该事件的回调函数接收一个参数 ws,它是一个表示新连接的 WebSocket 实例。

  1. 处理连接
javascript 复制代码
console.log('connected')

当客户端连接到服务器时,会在控制台上打印 connected

  1. 监听 message 事件
javascript 复制代码
ws.on('message', function incoming(message) {
  console.log('received: %s', message)
  ws.send('echo: ' + message)
})

当服务器从连接的客户端接收到消息时,message 事件会被触发。在回调函数中,首先打印接收到的消息内容,然后向客户端发送一个带有 echo: 前缀的响应消息。

  1. 监听 close 事件
javascript 复制代码
ws.on('close', function close() {
  console.log('disconnected')
})

当 WebSocket 连接关闭时,close 事件会被触发。在回调函数中,打印 disconnected 表示连接已断开。

  1. 发送欢迎消息
javascript 复制代码
ws.send('Welcome to the WebSocket server!')

当客户端连接后,服务器会立即发送一条欢迎消息给客户端。

WebSocket 客户端

代码:

html 复制代码
<!DOCTYPE html>
<html>
<head>
   <meta charset="UTF-8">
   <title>梦幻星辰吧 Client</title>
</head>
<body>
<script>
   window.onload = function () {
       var nick = prompt("Enter your nickname");
       var input = document.getElementById("input");
       input.focus();

       // 初始化客户端套接字并建立连接
       var socket = new WebSocket("ws://localhost:3000");
       
       // 连接建立时触发
       socket.onopen = function (event) {
           console.log("Connection open ..."); 
       }

       // 接收到服务端推送时执行
       socket.onmessage = function (event) {
           var msg = event.data;
           var node = document.createTextNode(msg);
           var div = document.createElement("div");
           div.appendChild(node);
           document.body.insertBefore(div, input);
           input.scrollIntoView();
       };
       
       // 连接关闭时触发
       socket.onclose = function (event) {
           console.log("Connection closed ..."); 
       }

       input.onchange = function () {
           var msg = nick + ": " + input.value;
           // 将输入框变更信息通过 send 方法发送到服务器
           socket.send(msg);
           input.value = "";
       };
   }
</script>
<input id="input" style="width: 100%;">
</body>
</html>

解读:

当页面加载完成时,会执行window.onload中的函数。

  1. 获取昵称:
javascript 复制代码
var nick = prompt("Enter your nickname");

通过prompt函数,页面会弹出一个提示框,要求用户输入其昵称,并将其赋值给nick变量。

从DOM中获取ID为"input"的元素,并设置其为当前焦点,这样用户可以直接开始输入。

  1. 初始化WebSocket连接:
javascript 复制代码
var socket = new WebSocket("ws://localhost:3000");

创建一个新的WebSocket对象,并尝试与在本地主机上运行的、端口号为3000的WebSocket服务器建立连接。

  1. 处理连接打开事件:
javascript 复制代码
socket.onopen = function (event) {
   console.log("Connection open ..."); 
};

当WebSocket连接成功打开时,此函数会被触发,并在控制台输出"Connection open ..."。

  1. 处理接收到的消息:
javascript 复制代码
socket.onmessage = function (event) {
   var msg = event.data;
   var node = document.createTextNode(msg);
   var div = document.createElement("div");
   div.appendChild(node);
   document.body.insertBefore(div, input);
   input.scrollIntoView();
};

当从服务器接收到消息时,此函数会被触发。消息内容存储在event.data中。然后,代码会创建一个新的div元素,将消息内容作为文本节点添加到该div中,并将该div插入到输入框前面。最后,通过scrollIntoView()方法确保输入框在视口中可见。

  1. 处理连接关闭事件:
javascript 复制代码
socket.onclose = function (event) {
   console.log("Connection closed ..."); 
};

当WebSocket连接关闭时,此函数会被触发,并在控制台输出"Connection closed ..."。

  1. 处理输入框内容变更:
javascript 复制代码
input.onchange = function () {
   var msg = nick + ": " + input.value;
   socket.send(msg);
   input.value = "";
};

当输入框的内容发生变化时(例如,用户输入文本并按下Enter键),此函数会被触发。它创建一个消息字符串,其中包含用户昵称和输入框的值,并通过socket.send()方法发送到服务器。然后,清空输入框的值,以便用户可以继续输入新的消息。

运行结果:

用serve或其他工具启动web服务,访问客户端页面,

服务端这个时候接收到客户端的链接请求,并打印如下信息:

输入之后点击确定,JavaScript 代码会继续往下执行,让输入框获取焦点,然后初始化 WebSocket 客户端并连接到服务器,这个时候通过开发者工具可以看到 Console 标签页已经输出了连接已建立日志

这个时候我们在客户端输入,client,WebSocket!

服务端通过该方法,

js 复制代码
  // 当接收到客户端消息时,打印消息内容并将其发送回客户端
  ws.on('message', function incoming(message) {
    console.log('received: %s', message)
    ws.send('echo: ' + message)
  })

接收到信息,并打印:

总结:

哈哈,你可能会觉得!虽然这段代码里看起来像是客户端主动找服务器要消息,但WebSocket的真正魅力在于,一旦它们"握手"成功,服务器就能变成个"消息小达人",随时随地给客户端推送最新动态。就像你在网上订了个外卖,不用一直刷新页面看厨师做好了没,厨师做好后会直接通知你一样。

在实际项目中,WebSocket 就像一个永不休息的快递员,不管白天黑夜,只要有新的"包裹"(消息),它就会立刻送到你的手上。这样,你就不再需要时不时地去"邮局"(服务器)查询了,轻松又方便!

所以,别小看这简单的几行代码,它们可是实现实时通信的"神器"哦!下次当你看到那些实时更新的信息、聊天界面的消息闪烁时,不妨想想背后的WebSocket"小达人"们,它们正在默默地为你传递着世界的最新动态呢!

相关推荐
腾讯TNTWeb前端团队3 小时前
helux v5 发布了,像pinia一样优雅地管理你的react状态吧
前端·javascript·react.js
范文杰7 小时前
AI 时代如何更高效开发前端组件?21st.dev 给了一种答案
前端·ai编程
拉不动的猪7 小时前
刷刷题50(常见的js数据通信与渲染问题)
前端·javascript·面试
拉不动的猪7 小时前
JS多线程Webworks中的几种实战场景演示
前端·javascript·面试
FreeCultureBoy8 小时前
macOS 命令行 原生挂载 webdav 方法
前端
uhakadotcom8 小时前
Astro 框架:快速构建内容驱动型网站的利器
前端·javascript·面试
uhakadotcom8 小时前
了解Nest.js和Next.js:如何选择合适的框架
前端·javascript·面试
uhakadotcom8 小时前
React与Next.js:基础知识及应用场景
前端·面试·github
uhakadotcom9 小时前
Remix 框架:性能与易用性的完美结合
前端·javascript·面试
uhakadotcom9 小时前
Node.js 包管理器:npm vs pnpm
前端·javascript·面试