基于 Server-sent Events 的实时消息推送系统

随着互联网技术的不断发展,实时消息推送成为了现代网站必不可少的功能之一。在前端方面,如果需要实现实时消息推送,通常会使用 WebSockets 技术。但是,WebSockets 技术需要浏览器和服务器之间建立一个持久连接,这会影响服务器的性能和扩展性。而 Server-sent Events 技术则是一种更加轻量级的实时消息推送方案。

Server-sent Events(也称为“EventSource”)是一种基于 HTTP 的服务器向浏览器推送消息的技术。它是一种单向通信协议,从服务器向客户端推送消息,而客户端不能向服务器发送消息。Server-sent Events 的设计目的是为了提供一种更加轻量级的实时消息推送解决方案。

为什么使用 Server-sent Events?

相比于 WebSockets 技术,Server-sent Events 有以下优点:

  • 更加轻量级。 因为 Server-sent Events 是一种基于 HTTP 的技术,所以它不需要建立持久连接,也不会有额外的握手和协议开销。
  • 更容易实现。 Server-sent Events 是基于 HTTP 的,因此它可以很容易地与现有的 Web 应用程序集成。它还不需要特殊的客户端库或软件。

Server-sent Events 的一些限制包括:

  • 浏览器兼容性。 虽然大多数现代浏览器都支持 Server-sent Events,但仍有一些浏览器不支持该技术(如 Internet Explorer)。
  • 单向通信。 Server-sent Events 是一种单向通信协议,这意味着客户端不能向服务器发送消息。如果需要双向通信,WebSockets 仍然是更好的选择。

实现一个基于 Server-sent Events 的实时消息推送系统

在本节中,我们将演示如何使用 Node.js 和 Express 框架构建一个基于 Server-sent Events 的实时消息推送系统。这个系统将允许用户向服务器发送一条消息,然后实时地将该消息推送到所有连接的客户端。

步骤 1:设置基本环境

我们将使用 Node.js 和 Express 框架构建我们的应用程序。首先,我们需要确保 Node.js 和 NPM 安装在我们的机器上。然后,使用以下命令初始化一个新的 Node.js 项目:

在 npm init 过程中,我们将需要回答一些问题来设置我们的项目。

接下来,我们需要安装 Express 框架:

步骤 2:实现服务器端代码

在这一步中,我们将实现服务器端代码,并使用 Express 框架来处理 HTTP 请求和响应。

创建 WebSocket 服务器

我们将使用 Node.js 的 http 模块创建一个 HTTP 服务器,然后使用 Express 框架来处理 HTTP 请求和响应。在 app.js 文件中,我们可以使用以下代码创建服务器:

const http = require('http');
const app = require('express')();

const server = http.createServer(app);

server.listen(3000, () => {
  console.log('Server running on port 3000');
});

处理 HTTP 请求和响应

我们需要在 Express 中设置路由来处理客户端和服务器之间的消息传递。在这个例子中,我们将设置一个路由来处理 WebSocket 连接请求,以及一个路由来处理客户端发送的消息。设置路由的代码如下:

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

  // TODO: 接入 Redis

  const data = 'data: Hello from the server!\n\n';
  res.write(data);
});

app.post('/message', (req, res) => {
  const message = req.body.message;
  console.log(`Received message: ${message}`);

  // TODO: 将消息推送给所有连接的客户端

  res.sendStatus(200);
});

推送消息到客户端

我们需要使用 Server-sent Events 协议来向客户端推送消息。在 express 中,我们可以使用 res.write() 方法向客户端推送消息。在以下示例中,我们将向客户端推送一个简单的消息:

const data = 'data: Hello from the server!\n\n';
res.write(data);

我们需要在客户端上设置一个 EventSource 来处理从服务器推送的消息。在以下示例中,我们将创建一个新的 EventSource,并使用 onmessage 事件处理程序来处理从服务器接收到的消息:

const eventSource = new EventSource('/stream');
eventSource.addEventListener('message', function(event) {
  console.log(`Received message: ${event.data}`);
});

步骤 3:实现客户端代码

在这一步中,我们将实现客户端代码,并将我们的应用程序连接到服务器,以接收从服务器推送的消息。

创建连接到服务器的 WebSocket

我们需要在客户端中创建一个 WebSocket 连接,以便从服务器接收推送。在以下示例中,我们将创建一个新的 WebSocket 连接,将其连接到我们的服务器,并使用 onmessage 事件处理程序来处理从服务器接收到的消息:

const socket = new WebSocket('ws://localhost:3000');
socket.addEventListener('message', function(event) {
  console.log(`Received message: ${event.data}`);
});

发送消息到服务器

我们需要在客户端上设置一个表单,以允许用户输入消息并将它们发送到服务器。在以下示例中,我们将创建一个新的表单,使用 XMLHttpRequest 对象将消息发送到服务器,然后将表单重置为接收另一条消息:

const form = document.getElementById('message-form');
const input = document.getElementById('message-input');

form.addEventListener('submit', function(event) {
  event.preventDefault();

  const message = input.value;
  const data = JSON.stringify({ message: message });

  const xhr = new XMLHttpRequest();
  xhr.open('POST', '/message');
  xhr.setRequestHeader('Content-Type', 'application/json');
  xhr.send(data);

  input.value = '';
});

总结

Server-sent Events 是一种很好的实时消息推送解决方案,它使用基于 HTTP 的单向通信协议。虽然它有一些限制,但它比 WebSockets 技术更加轻量级和易于实现。在本文中,我们演示了如何使用 Node.js 和 Express 框架构建一个基于 Server-sent Events 的实时消息推送系统。我们介绍了一些简单的示例代码,以帮助你开始创建你自己的 Server-sent Events 应用程序。

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