WebSocket 是 HTML5 提供的一种基于 TCP 的全双工通信协议,常用于浏览器与服务器之间的实时通信场景,如聊天室和直播等。但是 WebSocket 在不稳定网络下,可能会出现连接断开的情况,此时可以通过 Server-sent Events 实现 WebSocket 断线重连机制,保证通信的持续性和可靠性。
Server-sent Events 是什么
Server-sent Events 是 HTML5 新增的一种 Server Push 技术,用于实现服务器向客户端推送事件的功能。使用 Server-sent Events 不需要像 WebSocket 那样建立额外的握手,可以通过浏览器原生支持的 EventSource API 接收到服务端的数据。
要使用 Server-sent Events,需要在服务器端设置响应头,如下:
Content-Type: text/event-stream Cache-Control: no-cache Connection: keep-alive
这些响应头会告诉浏览器该响应是 Server-sent Events 类型,无需缓存,且保持连接。
在客户端,可以使用 JavaScript 代码创建 EventSource 实例,并监听服务端推送的事件,如下:
const eventSource = new EventSource('/updates'); eventSource.onmessage = (event) => { console.log(event.data); }; eventSource.onerror = (event) => { console.error(event); };
这里创建了一个 EventSource 实例,指向服务端 /updates
接口,然后监听 onmessage 事件,接收到服务端发送的数据后打印到控制台。同时监听 onerror 事件,处理连接异常。
在服务端,可以使用任何后端开发语言实现 Server-sent Events 推送,只需要按照上面的规范设置响应头和发送数据即可。
为了保证 WebSocket 断线后能够重新连接,可以借助 Server-sent Events 实现自动断线重连机制。具体实现方法如下:
- 客户端建立 WebSocket 连接,并设置心跳机制,定时向服务端发送消息,以保持连接。
// javascriptcn.com 代码示例 let socket = new WebSocket('ws://localhost:3000'); let timer = null; socket.onopen = () => { console.log('WebSocket 连接已建立'); // 设置心跳机制 timer = setInterval(() => { socket.send('ping'); }, 5000); };
- 客户端监听 WebSocket 的 close 事件,在连接关闭时启动 Server-sent Events 推送,通过监听服务端推送的事件,自动重连 WebSocket。
// javascriptcn.com 代码示例 socket.onclose = () => { console.log('WebSocket 连接已关闭,启动自动重连机制'); // 启动 Server-sent Events 推送 let eventSource = new EventSource('/reconnect'); eventSource.onmessage = (event) => { console.log(event.data); // 连接成功后关闭 Server-sent Events 推送,重新建立 WebSocket 连接 if (event.data === 'success') { eventSource.close(); socket = new WebSocket('ws://localhost:3000'); // 重新建立连接后重新设置心跳机制 socket.onopen = () => { console.log('WebSocket 连接已重新建立'); clearInterval(timer); timer = setInterval(() => { socket.send('ping'); }, 5000); }; } } };
- 服务端监听
/reconnect
接口,当有客户端连接时,通过 Server-sent Events 推送发送事件,通知客户端可以重新建立 WebSocket 连接。
// javascriptcn.com 代码示例 app.get('/reconnect', (req, res) => { res.setHeader('Content-Type', 'text/event-stream'); res.setHeader('Cache-Control', 'no-cache'); res.setHeader('Connection', 'keep-alive'); res.flushHeaders(); res.write('data: start\n\n'); // 监听客户端的连接,若连接成功,则发送 success 事件通知客户端重新建立 WebSocket 连接 req.on('close', () => { console.log('客户端已断开连接'); }); setInterval(() => { res.write('data: reconnect\n\n'); }, 5000); });
这样,当 WebSocket 连接断开时,客户端会自动启动 Server-sent Events 推送,等待服务端的通知,一旦收到可重新建立 WebSocket 连接的信号,就可以立即重新建立连接,并继续保持通信。整个过程对于用户来说是无感知的,对于开发者来说,提升了 WebSocket 连接的可靠性和稳定性。
总结
本文介绍了使用 Server-sent Events 实现 WebSocket 断线重连机制的方法。Server-sent Events 是一种浏览器原生支持的 Server Push 技术,可以用于向客户端推送数据和服务端事件。结合 WebSocket,可以实现多种复杂场景下的实时通信,并提升通信的可靠性和稳定性。
来源:JavaScript中文网 ,转载请注明来源 本文地址:https://www.javascriptcn.com/post/652b5af57d4982a6ebd4e560