JavaScript 流式传输数据 SSE (Server-Sent Events)

878 阅读1分钟

简介

在调用通义千问的流式接口时,内容是流式的一点点生成的。这里使用的并不是 WebSocket 而是 SSE(Server-Sent Events)

流式响应允许服务器在数据完全生成之前就开始向客户端发送数据。SSE 是一种允许服务器主动向客户端推送更新的技术。与 WebSocket 不同,SSE 只支持单向通信(从服务器到客户端),但它更简单,只需要一个普通的 HTTP 连接。

以下是使用 JavaScript 创建 SSE 的基本步骤:

创建对象:在客户端使用 new EventSource(url) 方法创建一个新的 EventSource 实例,其中 url 参数是事件源的 URL 地址。
监听消息:通过添加事件监听器来接收来自服务器的消息。可以监听的消息类型包括 message、open 和 error。
处理消息:当收到消息时,根据需要处理这些消息,例如更新网页内容。
关闭连接:如果不再需要接收更新,可以通过调用 EventSource 实例的 close() 方法来关闭连接。

下面是一些例子,演示如何使用 JavaScript 来设置 SSE 并监听服务器发送的事件:

HTML页面:

<!DOCTYPE html>
<html>
<head>
  <title>SSE Test</title>
</head>
<body>
  <div id="messages"></div>
  <script>
    const eventSource = new EventSource('/sse');
 
    eventSource.onmessage = function(event) {
      document.getElementById('messages').innerHTML += event.data + '<br>';
    };
  </script>
</body>
</html>

Node.js 服务端

const http = require('http');
 
const server = http.createServer((req, res) => {
  if (req.url === '/sse') {
    // 设置Content-Type头部以及允许跨域
    res.setHeader('Content-Type', 'text/event-stream');
    res.setHeader('Access-Control-Allow-Origin', '*');
 
    // 发送一个初始的数据块
    res.write('data: Initial data\n\n');
 
    // 定时发送事件
    setInterval(() => {
      const data = `data: ${new Date().toISOString()}\n\n`;
      res.write(data);
    }, 1000);
 
    // 如果客户端关闭连接,则终止定时器
    req.on('close', () => {
      clearInterval(interval);
    });
  } else {
    res.end('Not Found');
  }
});
 
server.listen(3000, () => {
  console.log('Server is running on http://localhost:3000/sse');
});

使用 Express.js 的例子

const express = require('express');
const app = express();
const port = 3000;
 
app.get('/events', (req, res) => {
  // 设置Content-Type头信息为'text/event-stream'
  res.setHeader('Content-Type', 'text/event-stream');
  res.setHeader('Cache-Control', 'no-cache');
 
  // 每隔一秒发送一次数据
  setInterval(() => {
    const data = `data: ${new Date().toISOString()}\n\n`;
    res.write(data);
  }, 1000);
 
  // 当客户端断开连接时,停止发送事件
  req.on('close', () => {
    console.log('Client disconnected');
    clearInterval(interval);
  });
});
 
app.listen(port, () => {
  console.log(`Server is running on port ${port}`);
});

来源:javascript.net.cn/articles/12…