WebSocket原理&使用

WebSocket 与HTTP的区别

与传统的HTTP协议相比,WebSocket具有以下几个显著的区别:

  • 双向通信:WebSocket 协议通过建立一条持久化的连接来实现双向通信,而HTTP协议是单向请求-响应模式
  • 低延迟: 由于WebSocket 使用长链接,避免了HTTP的链接建立和断开过程,可以降低通信延迟
  • 更少的数据传输: WebSocket 头部信息相对较小,减少了数据传输的开销
  • 跨域支持: WebSocket 可以轻松跨域,而HTTP需要通过CORS等机制来实现跨域。

WebSocket的工作原理

  • WebSocket的握手过程和HTTP有所不同。在使用 WebSocket 协议时,客户端和服务器会进行一次握手过程,以建立起 WebSocket 连接。握手过程中,客户端会发送一个 HTTP 请求,请求头中包含 Upgrade 和 Connection 字段,告诉服务器它希望升级到 WebSocket 连接。服务器收到请求后会返回一个 HTTP 响应,响应头中包含 Upgrade 和 Connection 字段,以及一个 Sec-WebSocket-Accept 字段,用于验证请求的合法性。握手成功后,客户端和服务器就可以开始使用 WebSocket 协议进行通信了

  • 建立链接后,客户端和服务器之间可以通过WebSocket发送喝接收消息,可以使用文本、二进制数据等进行通信。

WebSocket应用场景

  • 即时聊天: WebSocket可以实现实时的聊天功能,用户可以发送和接收消息,实现快速、低延迟的聊天体验。
  • 实时数据更新: 对于需要实时更新数据的应用,如股票行情、实时监控等,WebSocket可以将数据实时推送给客户端,确保数据的及时更新。
  • 在线游戏: 在线游戏需要实时的双向通信,WebSocket可以提供稳定的通信通道,支持实时交互和多人游戏。

WebSocket 的使用

示例代码:

var Socket = new WebSocket("url, [protocol]");

以上代码中的第一个参数url,指定链接的url。第二个参数protocol是可选参数,指定可接受的子协议。

WebSocket属性

  • Socket.readyState: 只读熟悉readyState表示链接状态,可以是以下值:0-表示尚未建立链接。1-表示链接已建立,可以进行通信。2-表示链接正在进行关闭。3-表示链接已经关闭或者链接不能打开
  • Socket.bufferedAmount: 只读属性bufferedAmount已被send()放入正在队列中等待传输,但是还没有发出的UTF-8文本字节数。

WebSocket事件

事件 事件处理程序 描述
open Socket.onopen 链接建立时触发
message Socket.onmessage 客户端接收服务端数据时触发
error Socket.onerror 通信发生错误时触发
close Socket.onclose 连接关闭时触发

WebSocket 方法

方法 描述
Socket.send() 使用链接发送数据
Socket.close() 关闭链接

WebSocket设置心跳机制

WebSocket的心跳机制是一种用于保持WebSocket连接的稳定性和活跃性的方法。

  • 定义心跳间隔: 为了定期发送心跳消息,你需要定义一个心跳间隔,通常以毫秒为单位。
 const heartbeatInterval = 30000; // 30秒

  • 定义心跳消息: 定义用于发送心跳的消息内容。
const heartbeatMessage = 'heartbeat';

  • 设置心跳定时器: 一旦WebSocket链接打开,可使用setInterval函数设置一个定时器,以便每隔一段实践发送心跳消息。
let heartbeat;

socket.addEventListener('open', () => {
    console.log('WebSocket连接已打开');

    heartbeat = setInterval(() => {
        socket.send(heartbeatMessage);
    }, heartbeatInterval);
});

  • 处理心跳消息: 当接收到来自服务器的消息时,需要检查它是否是心跳消息,这可以通过比较接收到的消息内容和心跳消息内容来实现。
socket.addEventListener('message', (event) => {
    const message = event.data;

    if (message === heartbeatMessage) {
        console.log('接收到心跳消息');
        // 在这里可以执行一些处理心跳消息的操作
    } else {
        console.log('接收到其他消息:', message);
        // 处理其他类型的消息
    }
});

  • 清除心跳定时器: 当WebSocket链接关闭时,你应该清除之前设置的心跳定时器,以防止继续发送心跳消息。
socket.addEventListener('close', () => {
    console.log('WebSocket连接已关闭');

    clearInterval(heartbeat);
});

WebSocket的安全性

WebSocket支持通过 wss:// 前缀建立加密的安全链接,使用TLS/SSL加密通信,确保数据的安全性。在使用加密链接时,服务器需要配置相应的证书。

WebSocket的跨域问题

对于跨域问题,WebSocket遵循同源策略,只能与同源的服务器建立链接。如果需要与不同服务器通信,可以使用CORS(跨域资源共享)来进行跨域访问控制。

WebSocket第三方库

  • Socket.io-client
  • ReconnectingWebSocket
  • SockJS-client
  • RxJs WebSocketSubject
  • autobahn.js