SSE 实现客户端与服务端间的双向通讯

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


纠错反馈