SSE 实现客户端与服务端间的双向通讯
随着 Web 技术的发展,越来越多的应用需要在前端与服务端之间进行实时通信,比如聊天室、实时在线游戏等。而传统的 Ajax 请求方式需要客户端不断轮询服务端接口获取最新数据,造成了较大的带宽和性能浪费,同时也无法实现真正的实时通信。在这种情况下,Server-Sent Events(SSE)技术应运而生,它可以实现服务器主动向客户端推送数据,实现双向实时通信。
SSE 是 HTML5 新增的标准特性之一,它基于 HTTP 协议,使用了长连接与流的方式,实现了服务器向客户端的单向、持续的数据推送,且不需要任何握手等预处理,不同于 WebSocket,SSE 标识上可读性好,其协议允许了请求、响应的敏感性以及事件处理器的支持。接下来,我们将会详细介绍 SSE 技术是如何实现客户端与服务端间的双向通讯。
服务端 SSE 实现
服务端 SSE 的实现方式比较简单。首先,你需要创建一个接口,该接口需要使用 text/event-stream
数据格式,以及 Content-Type
设置为 text/event-stream
,并在服务端设置 Cache-Control:no-cache
等相关缓存控制的首部字段,示例代码如下:
const http = require('http'); const server = http.createServer((req, res) => { res.writeHead(200, { 'Content-Type': 'text/event-stream', 'Cache-Control': 'no-cache', }); // 利用 ES 定时发送数据到客户端 setInterval(() => { res.write('data: ' + new Date().toISOString() + '\n\n'); }, 1000); }); server.listen(3000); console.log('Server running at http://localhost:3000/');
当客户端请求该接口时,服务端会不断地在 setInterval()
内向客户端发送数据,每次发送的数据需要以 data:
开头,并以两个换行符结尾,告诉浏览器这是一个新的事件数据。由于浏览器默认对数据进行缓存,对于事件流数据也不例外,即使数据已经变了,在浏览器看来数据仍然和之前一样。因此,我们需要在响应的首部信息中添加 Cache-Control:no-cache
,使浏览器不会对事件流进行缓存。
客户端 SSE 实现
在前端中实现 SSE 也非常简单,可以使用 EventSource
API 获取服务器推送的数据。下面是一个简单的示例:
const source = new EventSource('/sse'); // 处理消息事件 source.addEventListener('message', function(e) { const data = e.data; console.log(data); }, false); // 处理错误事件 source.onerror = function(e) { console.log('SSE error:', e); }; // 关闭事件流 setTimeout(function() { source.close(); }, 5000);
通过 new EventSource('/sse')
方法创建一个 EventSource 对象,该对象会通过 HTTP GET 方法发起一个 SSE 请求,请求地址为 /sse
。一旦服务端有数据推送过来,message
事件将被触发,通过 e.data
得到服务器推送的数据。当然,如果在处理 SSE 数据时出现错误,可以通过 onerror()
事件进行异常处理。
总结
通过上述实现,在服务端数据发生变化时,即可实现实时向前端推送数据,并且可以实现客户端与服务端双向通讯,非常适用于实时性要求比较高的应用中。当然,在实际应用中,还需要考虑缓存、断线重连、吞吐量控制等问题。如果你正在开发实时通信应用,不妨尝试使用 SSE 技术,看看能否提高应用的性能和用户体验。
来源:JavaScript中文网 ,转载请注明来源 本文地址:https://www.javascriptcn.com/post/65a8c533add4f0e0ff1f7778