如何使用 Server-sent Events 实现客户端与服务端的双向通信

前言

在现代网络应用中,实时双向通信已经成为了必须的需求。通过 HTTP 请求,浏览器只能接收来自服务端的响应数据,并不能直接接收服务端主动推送的消息。但是,现在有一种叫做 Server-sent Events 的技术,可以让浏览器和服务端通过长连接实现实时通信。本文将详细介绍如何使用 Server-sent Events 实现客户端和服务端的双向通信。

什么是 Server-sent Events

Server-sent Events(简称 SSE)是一种 HTML5 中定义的技术,它提供了一种在 Web 应用程序中实现服务器到浏览器的单向实时通信的方法。一般来说,SSE 是建立在 HTTP 上面的,而且它主要是通过一种名为 "Event Stream" 的机制来传输数据。简单来说,就是浏览器可以与服务端建立一个持久的 HTTP 连接,服务端会不断的向浏览器推送数据,以此达到实时通信的目的。

如何使用 Server-sent Events

要使用 Server-sent Events,需要分为客户端和服务端两部分来实现。

客户端实现

客户端使用 SSE 也很简单,只需要在 JavaScript 中创建一个 EventSource 对象,然后监听它的 onmessage 事件。当服务器向客户端推送消息时,就会触发该事件,并将推送过来的数据作为该事件的参数。下面是一个 SSE 客户端的示例代码:

const source = new EventSource('/sse'); // 创建一个 EventSource 对象
source.onopen = (event) => {
  console.log('连接已建立');
};
source.onerror = (event) => {
  console.log('连接发生错误');
};
source.onmessage = (event) => {
  console.log('收到推送数据:', event.data);
};

上面代码中,我们通过 new EventSource('/sse') 创建了一个 SSE 连接,并监听 onopen、onerror 和 onmessage 事件。当连接建立时,onopen 事件会被触发,当连接发生错误时,onerror 事件会被触发,当服务器向客户端推送消息时,onmessage 事件会被触发。

服务端实现

服务端实现 SSE 也很简单,首先需要设置 HTTP 响应头 Content-Type 的值为 text/event-stream,这样浏览器就会以 Event Stream 的方式解析响应数据。然后,服务端需要不断地向客户端推送数据,并且每条数据都需要以特殊的格式进行发送,格式如下:

其中,event 字段表示该条数据的 SSE 事件名,可以省略;data 字段表示该条数据的内容。注意每个字段后面都需要加上一个换行符。

下面是一个 SSE 的服务端示例代码(使用 Node.js 和 Express 框架):

const express = require('express');
const app = express();
 
app.get('/sse', (req, res) => {
  res.writeHead(200, {
    'Content-Type': 'text/event-stream',
    'Cache-Control': 'no-cache',
    'Connection': 'keep-alive'
  });
  setInterval(() => {
    const data = JSON.stringify({msg: 'hello SSE'});
    res.write(`event: myevent\n`);
    res.write(`data: ${data}\n\n`);
  }, 1000);
});
 
app.listen(3000);

上面代码中,首先使用了 Express 框架创建了一个 SSE 接口 /sse。然后在该接口的响应头中,设置了 Content-Type 为 text/event-stream,Cache-Control 为 no-cache,Connection 为 keep-alive,这些都是 SSE 所必需的。接下来,我们使用 setInterval 定时向客户端推送数据。在每次推送数据时,我们需要按照特定的格式发送数据,其格式如上所述。

总结

通过本文的介绍,相信大家已经了解了如何使用 Server-sent Events 实现客户端与服务端的双向通信。要注意的是,SSE 主要是用来实现单向实时通信的,如果需要实现双向实时通信,可以考虑使用 WebSocket。最后,如果您想了解 Server-sent Events 更多的细节和技巧,可以查看 MDN 上的详细文档。

来源:JavaScript中文网 ,转载请注明来源 本文地址:https://www.javascriptcn.com/post/65907014eb4cecbf2d5d16a8


纠错
反馈