WebSocket

201 阅读3分钟

WebSocket

原生 WebSocket 和 Socket.IO 都是用于在客户端和服务器之间建立实时通信的技术。但是,它们之间有一些关键的区别: 原生 WebSocket 是基于 TCP 的协议,而 Socket.IO 不仅支持 WebSocket,还支持 Polling 机制,即当 WebSocket 不可用时,会使用 HTTP 长轮询等方式进行数据传输。 Socket.IO 提供了更高级的实时通信能力,例如,它可以自动管理连接,并在客户端和服务器之间实现消息的路由。 Socket.IO 支持事件,这意味着它可以发送具有特定事件名称的消息,而在接收端,只有绑定了相同事件名称的监听器才能接收和处理这些消息。 因此,如果你想要在客户端和服务器之间建立实时通信,并且不介意在不支持 WebSocket 的环境中也能够使用,那么可以选择 Socket.IO。如果你只关心原生的 WebSocket 通信,并且不介意如何处理不可靠的网络环境,那么可以直接使用原生 WebSocket。 以下是使用原生 WebSocket 和 Socket.IO 的简单示例:

原生WebSocket

服务端

const WebSocket = require('ws');
const wss = new WebSocket.Server({ port: 8080 });
 
wss.on('connection', function connection(ws) {
  ws.on('message', function incoming(message) {
    console.log('received:', message);
  });
 
  ws.send('something');
});

客户端

const ws = new WebSocket('ws://localhost:8080');
 
ws.onopen = function open() {
  console.log('WebSocket connected');
  ws.send('Hello Server');
};
 
ws.onmessage = function incoming(data) {
  console.log('received:', data.message);
};

reconnecting-websocket

reconnecting-websocket实际上是对 websocket api的封装,主要功能就是提供了自动重新连接的功能。

安装
reconnecting-websocket
使用
引入
import ReconnectingWebSocket from 'reconnecting-websocket';
创建 WebSocket 实例
const url = 'wss://example.com/socket'; // WebSocket 服务端的 URL
const protocols = []; // 可选的子协议数组
const options = {
  // 自动重新连接的选项(可选)
  connectionTimeout: 1000,
  maxRetries: 10,
};
const rws = new ReconnectingWebSocket(url, protocols, options);
监听事件
// 当连接成功建立时
rws.addEventListener('open', function(event) {
  console.log('Connected to the WebSocket server');
});
 
// 当接收到消息时
rws.addEventListener('message', function(event) {
  console.log('Received message:', event.data);
});
 
// 当连接关闭时
rws.addEventListener('close', function(event) {
  console.log('Disconnected from the WebSocket server');
});
 
// 当发生错误时
rws.addEventListener('error', function(event) {
  console.error('WebSocket encountered error:', event.error);
});
发送消息
rws.send('Your message here');
关闭连接
rws.close(code, reason); // `code` 和 `reason` 是可选参数
监听连接状态变化
console.log(rws.readyState); // 输出当前的连接状态

readyState 属性的可能值如下:

  • 0 (WebSocket.CONNECTING): 正在连接。
  • 1 (WebSocket.OPEN): 已经连接并且可以通信。
  • 2 (WebSocket.CLOSING): 正在关闭连接。
  • 3 (WebSocket.CLOSED): 连接已关闭或无法打开。
手动控制重连
// 手动断开连接,并阻止自动重连
rws.close();
 
// 之后,如果你又想重新启用自动重连
rws.reconnect();
使用事件监听器的替代方法
rws.onopen = function(event) {
  console.log('Connected to the WebSocket server');
};
rws.onmessage = function(event) {
  console.log('Received message:', event.data);
};
rws.onclose = function(event) {
  console.log('Disconnected from the WebSocket server');
};
rws.onerror = function(event) {
  console.error('WebSocket encountered error:', event.error);
};
配置选项

ReconnectingWebSocket 提供了一些配置选项,允许你自定义重连行为:

  • debug: 是否启用调试模式,默认为 false。
  • automaticOpen: 是否在实例化时自动打开连接,默认为 true。
  • reconnectInterval: 重新连接尝试之间的间隔时间(毫秒),默认为 1000。
  • maxReconnectInterval: 重新连接尝试之间的最大间隔时间(毫秒),默认为 30000。
  • reconnectDecay: 用于增加 reconnectInterval 的乘数,每次尝试重连后会递增,默认为 1.5。
  • timeoutInterval: 关闭连接前等待服务器响应的最大时长(毫秒),默认为 2000。
  • maxRetries: 最大重连尝试次数,设为 null 代表无限尝试,默认为 null。
  • binaryType: 发送和接收二进制数据的类型,可以是 'blob' 或 'arraybuffer',默认为 'blob'。

Socket.io

服务端

const io = require('socket.io')(8080);

io.on('connection', (socket) => {
  socket.emit('event', 'Hello Client');
  
  socket.on('event', (data) => {
    console.log('received: ', data);
  });
});

客户端

const socket = io('http://localhost:8080');
 
socket.on('connect', function() {
  console.log('Socket connected');
  socket.emit('event', 'Hello Server');
});
 
socket.on('event', (data) => {
  console.log('received: ', data);
});

参考资料