JS — webscoket详解
一.基本概念
- WebSocket是一种在Web浏览器和服务器之间建立全双工通信的协议。它允许网页实时地发送和接收数据,而不需要页面刷新或像传统HTTP协议那样的轮询操作。
- WebSocket使用HTTP协议进行握手,并通过Upgrade头字段指定从HTTP到WebSocket的转换。一旦握手成功,WebSocket连接就会建立,并且可以在客户端和服务器之间开始实时双向通信。通过WebSocket,服务器可以向客户端推送数据,而不需要等待客户端请求数据。
- WebSocket协议支持跨域通信,因此可以在任何Web域之间建立实时连接。它还提供了强大的可靠性,自动重连机制和数据压缩功能,使其成为在Web应用程序中实现实时通信的理想选择。
二.握手过程
- 客户端发起握手请求:客户端通过普通的HTTP请求向服务器发起WebSocket握手请求。这个请求包含了一些特殊的头部,例如
Upgrade: websocket
和Connection: Upgrade
,以及一个随机的Sec-WebSocket-Key头部。这些头部告诉服务器这是一个WebSocket握手请求,并且要求升级到WebSocket协议。
- 服务器响应握手请求:服务器收到握手请求后,如果支持WebSocket协议,就会发送一个HTTP 101状态码(Switching Protocols),表示同意升级到WebSocket协议。响应头中也会包含类似的特殊头部,如
Upgrade: websocket
和Connection: Upgrade
,以及一个经过计算的Sec-WebSocket-Accept头部,用于验证握手请求的合法性。
- 握手成功,建立连接:一旦客户端收到服务器的握手响应,并验证了其中的信息,握手过程就完成了。此时,客户端和服务器之间就建立了WebSocket连接,可以开始进行实时的双向通信。
- 在握手成功后,客户端和服务器就可以通过WebSocket连接发送和接收数据,而不需要再发送普通的HTTP请求和响应。这种实时的双向通信方式大大提高了Web应用程序的交互性和实时性。
三.实现步骤
-
服务器端设置:
- 在服务器上选择适合的编程语言和框架,如Node.js、Python或Java。
- 导入WebSocket库或使用相关模块/库来处理WebSocket连接。
- 创建服务器,并监听指定的端口。
- 接收来自客户端的连接请求并建立WebSocket连接。
- 处理连接建立、消息接收和断开连接等事件。
-
客户端设置:
- 在Web浏览器或移动应用程序中使用WebSocket API。
- 使用
new WebSocket(url)
创建WebSocket对象,其中url是服务器的地址。 - 注册事件处理程序,例如onopen(连接建立)、onmessage(接收消息)和onclose(连接关闭)等。
-
握手过程:
- 当客户端通过WebSocket对象发起连接请求时,服务器会返回HTTP 101切换协议的响应。
- 客户端检查响应头是否包含
Upgrade: websocket
和Connection: Upgrade
字段。 - 客户端和服务器通过交换Sec-WebSocket-Key生成新的密钥,以验证握手的有效性。
-
双向通信:
- 一旦握手成功,WebSocket连接就会建立。
- 客户端和服务器可以通过WebSocket对象的send()方法发送消息。
- 服务器可以使用WebSocket库的API将消息广播给所有连接的客户端。
- 客户端可以使用WebSocket对象的onmessage事件处理程序接收服务器发送的消息。
-
关闭连接:
- 当需要关闭连接时,客户端可以调用WebSocket对象的close()方法。
- 服务器可以关闭与特定客户端的连接,或者通过广播关闭所有连接。
四.高级特性
-
消息压缩:WebSocket支持对传输的消息进行压缩,以减少数据传输量和带宽消耗。常用的压缩算法包括Gzip和Deflate。
-
子协议:WebSocket支持定义和使用不同的子协议。子协议可以用于区分不同类型的消息或在不同的应用场景中使用不同的消息格式。
-
心跳检测:为了保持WebSocket连接的活跃和稳定,可以定期发送心跳消息来检测连接状态。如果长时间没有收到心跳响应,就可以判断连接已断开,并进行相应的处理。
-
安全性:WebSocket可以通过使用安全套接字层(SSL/TLS)来加密通信,确保数据传输的机密性和完整性。使用wss://协议可以建立安全的WebSocket连接。
-
断线重连:在网络不稳定或连接中断的情况下,WebSocket可以支持自动断线重连机制,尝试重新建立连接,以保持持久的通信。
-
认证和授权:WebSocket可以与身份验证和授权系统集成,以确保只有经过授权的用户才能建立连接并访问特定的资源。
-
广播和多路复用:服务器可以使用WebSocket库的API将消息广播给所有连接的客户端,或者将消息发送到特定的客户端。同时,多个消息可以通过多路复用技术同时传输,提高通信效率。
五.使用方式(确保已安装Node.js)
-
安装
ws
库: 在项目目录下打开终端,并运行以下命令来安装ws
库:npm install ws
-
服务器端配置: 创建一个
server.js
文件,并将以下代码复制到文件中:const WebSocket = require('ws'); // 创建WebSocket服务器并监听指定端口 const wss = new WebSocket.Server({ port: 8080 }); // 监听连接事件 wss.on('connection', (ws) => { console.log('新的WebSocket连接建立'); // 监听消息接收事件 ws.on('message', (message) => { console.log('收到消息:', message); // 回复消息给客户端 ws.send('服务器收到消息:' + message); }); // 监听连接关闭事件 ws.on('close', () => { console.log('WebSocket连接关闭'); }); });
-
客户端配置: 创建一个
client.html
文件,并将以下代码复制到文件中:<!DOCTYPE html> <html> <head> <title>WebSocket客户端</title> </head> <body> <input type="text" id="messageInput" placeholder="输入消息" /> <button onclick="send()">发送</button> <script> const socket = new WebSocket('ws://localhost:8080'); // 监听连接建立事件 socket.addEventListener('open', (event) => { console.log('WebSocket连接已建立'); }); // 监听消息接收事件 socket.addEventListener('message', (event) => { console.log('收到消息:', event.data); }); // 监听连接关闭事件 socket.addEventListener('close', (event) => { console.log('WebSocket连接已关闭'); }); function send() { const input = document.getElementById('messageInput'); const message = input.value; // 发送消息给服务器 socket.send(message); } </script> </body> </html>
-
运行:
- 在终端中运行
node server.js
启动WebSocket服务器。 - 在Web浏览器中打开
client.html
文件。 - 在输入框中输入消息并点击发送按钮。
- 查看服务器端和客户端的控制台输出,以及客户端页面上显示的消息。
- 在终端中运行
- 分解:
- 服务器端代码使用ws库创建了一个WebSocket服务器,并监听8080端口。
- 当有新的WebSocket连接建立时,会触发connection事件处理程序,打印相关信息。
- 对于每个连接,通过监听message事件可以接收客户端发送的消息,并在控制台上打印出来。然后,通过调用ws.send()方法,将回复发送给客户端。
- 当连接关闭时,会触发close事件处理程序,打印相关信息。
- 客户端代码在页面加载时创建了一个WebSocket对象,并与服务器建立连接。
- 监听open事件可以在连接建立后打印相关信息。
- 监听message事件可以接收服务器发送的消息,并在控制台上打印出来。
- 监听close事件可以在连接关闭后打印相关信息。
- send()函数在按钮点击时将输入框中的消息发送给服务器。