WebSocket

定义

websocket 是一种建立在浏览器和服务器之间建立长时间稳定连接的技术,在单个 tcp 连接上进行全双工通信的网络协议,可以实现服务器(客户端)和服务器之间的双向数据包传递,且不受跨域限制

使用场景

客户端和服务端连续长时间互相通信如

  1. 实时性要求较高的应用,如网络游戏、数据可视化大屏、在线聊天等
  2. 需要频繁交换数据的应用,比如在线编辑器、文件管理器等
  3. 需要推送服务的应用,比如实时数据监控、通知系统等
  4. 跨平台应用,比如桌面应用程序、移动应用程序

特点

全双工通讯

长连接,server 和浏览器可以互相持续发送新数据

技术实现——websocket 协议

基于特殊的升级协议(HTTP/1.1 Upgrade 或 HTTP/2)建立 TCP 连接。可以一个 server 对多个 client 通讯

数据格式

文本和二进制数据

跨域

websocket 对象原生支持跨域

WebSocket 事件

  • open
  • message
  • error
  • close

服务端使用

  1. 创建 socket 服务实例、服务端口 const wsServer = new ws.Server({ port: 8080 },cb);

  2. 监听客户端连接 wsServer.on(‘connection’, cb)

  3. 广播发送消息实现群聊 wsServer.clients

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// 第一步,安装ws和ws的声明文件
import ws from 'ws';
// 创建socket服务 8080端口
const wsServer = new ws.Server({ port: 8080 }, () => {
console.log('socket service is running at ws://localhost:8080');
});
// 监听客户端/浏览器连接
wsServer.on('connection', (socket) => {
// 监听客户端的消息
console.log('client connection');
socket.on('message', (e) => {
// 消息广播实现群聊
wsServer.clients.forEach((serverForClient) => {
// 客户端传来的消息是buffer格式
serverForClient.send(e.toString());
console.log(e.toString());
});
});
});

客户端使用

  1. 创建 websocket 实例 new WebSocket(‘ws://xxxx’)

    1
    2
    // websocket 协议 ws wss
    const wsClient = new WebSocket('ws://localhost:8080');
  2. 监听是否连接成功 socket.addEventListener(‘open’, cb)

    1
    2
    3
    wsClient.addEventListener('open', () => {
    console.log('ws connection');
    });
  3. 向服务端发送消息 socket.send

    1
    2
    3
    4
    5
    6
    7
    btn.addEventListener('click', () => {
    const msg: string = input.value;
    if (input.value) {
    wsClient.send(msg);
    input.value = '';
    }
    });
  4. 监听服务端返回的消息 socket.addEventListener(‘message’, cb)

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    wsClient.addEventListener('message', (e) => {
    console.log(e);
    if (e.data.type === state.MSG) {
    const li = document.createElement('li');
    li.innerHTML = e.data;
    ul.appendChild(li);
    } else {
    console.log('heart check');
    }
    });

扩展

消息广播(群聊)

服务端 wsServer.clients 以 set 形式存储每个连接 ws 的 client,遍历发送信息即可实现群聊

1
2
3
4
5
6
7
8
9
10
11
wsServer.on('connection', (socket) => {
// 监听客户端的消息
console.log('client connection');
socket.on('message', (e) => {
// 消息广播实现群聊
wsServer.clients.forEach((serverForClient) => {
// 客户端传来的消息是buffer格式
serverForClient.send(e.toString());
});
});
});

心跳检测

  1. 在实际使用过程中,由于网络波动、弱信号等原因,可能会导致 websocket 连接断开。
  2. 为了避免这种情况的发生,可以使用心跳机制来检测 websocket 是否正常连接
  3. 当发现连接断开时,可以尝试重新建立连接,并进行相应的处理
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
// socket长时间不使用 网络波动和弱网环境都会导致连接断开
// 心跳检测 进行保活 保持连接
const state = {
HEART: 1,
MSG: 2,
};
let heartInterval = setInterval(heartCheck, 3000);
function heartCheck() {
// ws state 为open才发送心跳,否则结束循环检测
if (wsClient.readyState === wsClient.OPEN) {
wsClient.send(
JSON.stringify({
type: state.HEART,
message: 'heart check',
})
);
} else {
clearInterval(heartInterval);
}
}

WebSocket
https://hugtyftg.github.io/2024/01/30/WebSocket/
作者
mmy@hugtyftg
发布于
2024年1月30日
许可协议