仅仅只会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"小达人"们,它们正在默默地为你传递着世界的最新动态呢!

相关推荐
golitter.3 分钟前
Ajax和axios简单用法
前端·ajax·okhttp
PleaSure乐事12 分钟前
【Node.js】内置模块FileSystem的保姆级入门讲解
javascript·node.js·es6·filesystem
雷特IT23 分钟前
Uncaught TypeError: 0 is not a function的解决方法
前端·javascript
长路 ㅤ   1 小时前
vite学习教程02、vite+vue2配置环境变量
前端·vite·环境变量·跨环境配置
亚里士多没有德7751 小时前
强制删除了windows自带的edge浏览器,重装不了怎么办【已解决】
前端·edge
micro2010141 小时前
Microsoft Edge 离线安装包制作或获取方法和下载地址分享
前端·edge
.生产的驴1 小时前
Electron Vue框架环境搭建 Vue3环境搭建
java·前端·vue.js·spring boot·后端·electron·ecmascript
awonw1 小时前
[前端][easyui]easyui select 默认值
前端·javascript·easyui
九圣残炎1 小时前
【Vue】vue-admin-template项目搭建
前端·vue.js·arcgis
柏箱2 小时前
使用JavaScript写一个网页端的四则运算器
前端·javascript·css