Server-Sent Events - 客户端保持连接

Server-Sent Events (SSE) 是一种在 Web 应用程序中保持连接的技术,它允许服务器向客户端推送事件,而无需客户端发出请求。它是一种基于 HTTP 的协议,与 WebSocket 不同,它只允许服务器向客户端发送数据,而不允许双向通信。

SSE 的优势在于它可以实现实时通信,而且相对于 WebSocket 更加轻量级,因为它不需要建立双向通信的通道。它适用于那些需要实时更新数据的应用程序,例如股票报价、即时通讯等。

SSE 的工作原理

SSE 是基于 HTTP 的协议,因此它使用 HTTP 连接与服务器通信。客户端向服务器发出一个 HTTP 请求,服务器将响应该请求并保持连接打开。一旦连接打开,服务器就可以向客户端发送事件,而客户端可以通过监听事件来获取数据。

在 SSE 中,服务器发送的数据被称为事件(event),它由一个事件类型和一个事件数据组成。事件类型是一个字符串,用于标识事件的类型,而事件数据可以是任何有效的文本数据。

客户端可以通过 EventSource 对象来监听事件,它会自动处理服务器发送的事件。当服务器发送一个事件时,EventSource 对象会触发一个事件,客户端可以在该事件中获取事件类型和数据。

SSE 的使用

SSE 的使用非常简单,只需要在客户端创建一个 EventSource 对象,然后指定服务器的 URL 即可。服务器需要发送一些事件来与客户端通信。

下面是一个简单的 SSE 示例:

<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
  <title>SSE 示例</title>
</head>
<body>
  <h1>服务器时间</h1>
  <div id="time"></div>
  <script>
    var eventSource = new EventSource('/sse');

    eventSource.addEventListener('time', function(event) {
      var time = event.data;
      document.getElementById('time').innerHTML = time;
    }, false);
  </script>
</body>
</html>

在上面的示例中,我们创建了一个 EventSource 对象,并将服务器的 URL /sse 作为参数传递给它。服务器会定期发送一个名为 time 的事件,事件数据是服务器的当前时间。客户端监听 time 事件,并将事件数据显示在页面上。

服务器端的代码如下:

const http = require('http');

http.createServer((req, res) => {
  res.writeHead(200, {
    'Content-Type': 'text/event-stream',
    'Cache-Control': 'no-cache',
    'Connection': 'keep-alive'
  });

  setInterval(() => {
    res.write(`event: time\ndata: ${new Date().toLocaleString()}\n\n`);
  }, 1000);
}).listen(8080);

在上面的代码中,我们创建了一个 HTTP 服务器,并在每秒钟向客户端发送一个名为 time 的事件,事件数据是服务器的当前时间。注意到我们设置了响应头 Content-Typetext/event-stream,这是 SSE 的标准 MIME 类型。

SSE 的注意事项

虽然 SSE 看起来非常简单,但是在实际使用中需要注意一些问题。

首先,SSE 使用的是长轮询(long-polling)技术,因此它可能会导致服务器的负载增加。为了避免这个问题,服务器可以通过设置响应头 Cache-Control: no-cache 来禁用缓存,从而避免客户端发出不必要的请求。

其次,SSE 的事件数据必须是有效的文本数据,不能是二进制数据。如果需要发送二进制数据,可以使用 Base64 编码将其转换为文本数据。

最后,SSE 并不是所有浏览器都支持。虽然大多数现代浏览器都支持 SSE,但是一些老旧的浏览器可能无法支持它。如果需要兼容老旧的浏览器,可以考虑使用其他技术,例如轮询或 WebSocket。

总结

本文介绍了 SSE 技术,它是一种在 Web 应用程序中保持连接的技术,可以实现实时通信。我们讨论了 SSE 的工作原理、使用方法以及注意事项。虽然 SSE 看起来非常简单,但是在实际使用中需要注意一些问题。如果您需要实现实时通信的功能,可以考虑使用 SSE。

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


纠错
反馈