使用 Server-Sent Events 实现实时通信的 JavaScript 教程

在现代的 web 应用程序中,实时通信已经成为一个必不可少的特性。而 Server-Sent Events (SSE) 技术可以实现从服务器到客户端的实时消息传递,无需客户端发起请求,而且 SSE 的 API 非常简单易用。本文将介绍如何使用 SSE 实现实时通信,并提供详细的代码示例和指导。

SSE 基础知识

什么是 SSE?

Server-Sent Events 是一种从服务器向客户端推送消息的技术,它使用了基于 HTTP 协议的长连接。通过 SSE,服务器可以向客户端发送一系列的消息,而客户端无需发起请求,可以实时接收到这些消息。SSE 可以用于实现实时通知、实时聊天、实时数据更新等场景。

SSE 的 API

SSE 的 API 很简单,只需要使用 JavaScript 中的 EventSource 对象即可。EventSource 对象包含了三个主要的事件:

  • onopen:当 SSE 连接建立时触发。
  • onmessage:当服务器发送消息时触发。
  • onerror:当 SSE 连接关闭时触发。

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

const eventSource = new EventSource('/sse');
eventSource.onopen = () => {
  console.log('SSE connection opened.');
};
eventSource.onmessage = (event) => {
  console.log(`Received message: ${event.data}`);
};
eventSource.onerror = () => {
  console.log('SSE connection closed.');
};

SSE 消息格式

SSE 消息格式非常简单,每个消息都是一个纯文本的字符串,格式如下:

其中,event-name 表示事件名称,event-data 表示事件数据。注意,每个消息都必须以两个换行符结尾,否则客户端无法正确解析消息。

使用 SSE 实现实时通信

接下来,我们将使用 SSE 实现一个简单的实时聊天室。该聊天室包含两个页面:一个是发送消息的页面,另一个是接收消息的页面。

服务器端代码

首先,我们需要编写一个服务器端的程序,用于处理 SSE 请求和发送消息。在本例中,我们使用 Node.js 和 Express 框架来实现服务器端程序。下面是服务器端程序的代码:

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

// SSE 路由
app.get('/sse', (req, res) => {
  res.writeHead(200, {
    'Content-Type': 'text/event-stream',
    'Cache-Control': 'no-cache',
    'Connection': 'keep-alive'
  });
  res.write('\n');

  // 定时发送消息
  setInterval(() => {
    const message = `event: message\ndata: Hello, world!\n\n`;
    res.write(message);
  }, 1000);
});

// 静态文件路由
app.use(express.static('public'));

// 启动服务器
const port = 3000;
app.listen(port, () => {
  console.log(`Server listening on port ${port}.`);
});

在上面的代码中,我们定义了一个 SSE 路由 /sse,当客户端请求该路由时,服务器会返回一个 text/event-stream 类型的响应,并且使用 setInterval 定时向客户端发送消息。在本例中,我们发送的消息格式为 event: message\ndata: Hello, world!\n\n,表示事件名称为 message,事件数据为 Hello, world!

客户端发送消息页面

接下来,我们需要编写一个客户端页面,用于发送消息。下面是该页面的 HTML 和 JavaScript 代码:

<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
  <title>Send Message</title>
</head>
<body>
  <input type="text" id="message">
  <button id="send">Send</button>
  <script>
    const sendButton = document.getElementById('send');
    const messageInput = document.getElementById('message');

    sendButton.addEventListener('click', () => {
      const message = messageInput.value;
      messageInput.value = '';

      fetch('/message', {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json'
        },
        body: JSON.stringify({ message })
      });
    });
  </script>
</body>
</html>

在上面的代码中,我们创建了一个文本输入框和一个发送按钮,并通过 JavaScript 监听了发送按钮的点击事件。当用户点击发送按钮时,我们将输入框中的文本内容发送到服务器端。

客户端接收消息页面

最后,我们需要编写一个客户端页面,用于接收消息。下面是该页面的 HTML 和 JavaScript 代码:

<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
  <title>Receive Message</title>
</head>
<body>
  <ul id="messages"></ul>
  <script>
    const messagesList = document.getElementById('messages');

    const eventSource = new EventSource('/sse');
    eventSource.onopen = () => {
      console.log('SSE connection opened.');
    };
    eventSource.onmessage = (event) => {
      const data = JSON.parse(event.data);
      const message = document.createElement('li');
      message.textContent = data.message;
      messagesList.appendChild(message);
    };
    eventSource.onerror = () => {
      console.log('SSE connection closed.');
    };
  </script>
</body>
</html>

在上面的代码中,我们创建了一个无序列表,用于显示接收到的消息。当客户端向服务器发送消息时,服务器会将该消息通过 SSE 发送到客户端,并触发 onmessage 事件。在 onmessage 事件中,我们将接收到的消息解析为 JSON 对象,并将其添加到无序列表中。

总结

在本文中,我们介绍了如何使用 SSE 实现实时通信,并提供了一个简单的实时聊天室示例。SSE 技术非常简单易用,而且可以广泛应用于实时通知、实时聊天、实时数据更新等场景。如果你需要实现这些功能,不妨尝试使用 SSE。

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


纠错
反馈