简介
在调用通义千问的流式接口时,内容是流式的一点点生成的。这里使用的并不是 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}`);
});
使用 PHP 完成 SSE 的例子:
<?php
ini_set('output_buffering', 'off');
while (@ob_end_flush()) {}
header('Content-Type: text/event-stream');
header('Cache-Control: no-cache');
header('Connection: keep-alive');
header('X-Accel-Buffering: no');
// 开启输出缓冲
ob_start();
while (true) {
$number = rand(1, 10);
/**
* 每条消息由一行或多行字段组成,每个字段组成形式为:字段名: 字段值。
* 这里用data作为字段名,则前台可通过event.data来获取字段值
* 字段以行为单位,每行一个(即以 \n 结尾)。
* 每个消息之间以空行分隔(即最后一个字段以\n\n结尾)。
* 以冒号开头的行为注释行,会被浏览器忽略。
**/
echo "data: $number\n\n";
//刷新缓冲区
ob_flush();
//将输出缓冲区的内容立即发送到客户端
flush();
//模拟快速相应
sleep(1);
}
修改时间 2024-12-17
声明:本站所有文章和图片,如无特殊说明,均为原创发布。商业转载请联系作者获得授权,非商业转载请注明出处。