AI应用的流式输出,都在使用的 SSE 协议实现
自从 ChatGPT 发布后,各类基于 AI 大模型开发出来的应用百花齐放。
比如 AI 智能客服,知识库 各类 AI Agent,有关注这些工具在回复内容的时候,都是一个字一个字显示出来,不像搜索引擎直接返回一个网页的内容。
查看各类开源 AI 应用的源码实现,都是用 SSE 协议实现。
SSE协议简介
SSE(Server-Sent Events)是一种让服务器向浏览器推送信息的技术,基于HTTP协议,利用其长连接特性,在客户端与服务器之间建立持久连接,实现服务器向客户端的实时数据推送。
SSE是HTML5规范的一部分,由服务端与浏览器端的通讯协议和浏览器端的EventSource对象组成。
SSE 的一些关键特性:
- 单向通信:
SSE 仅支持服务器向客户端发送数据,客户端不能向服务器发送数据,这与WebSocket 不同,后者是双向通信。 - 长连接:
SSE 使用HTTP 长连接,服务器可以持续向客户端发送数据,而不需要客户端频繁地重新建立连接。 - 自动重连:
SSE 客户端在连接断开时会自动尝试重新连接,这使得SSE 具有较好的容错性和可靠性。 - 基于文本:
SSE 使用文本格式来传输数据,通常是text/event-stream,这使得调试和理解数据更容易。
SSE 的典型应用场景包括:
- 实时社交媒体更新:
例如,当有新消息或动态时,服务器可以立即推送给客户端。 - 股票行情更新:
股票市场的价格经常变动,SSE 可以让用户实时看到新的股票价格。 - 体育比分更新:
赛事比分、统计信息等,可以通过 SSE 在比赛进行时实时更新。
实时通知:
例如,当有新的订单、消息等,服务器可以主动通知客户端。 - IM 即时通讯
例如,客服 AI 工具
例子
网页前端代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>SSE示例</title>
</head>
<body>
<div id="result"></div>
<script>
// 检查浏览器是否支持EventSource
if (!!window.EventSource) {
var sse = new EventSource('sse.php');
// 监听消息事件
sse.onmessage = function (event) {
var resultDiv = document.getElementById('result');
resultDiv.innerHTML += event.data + '<br>';
};
// 监听打开连接事件
sse.onopen = function (event) {
console.log('连接已打开');
};
// 监听关闭连接事件
sse.onclose = function (event) {
console.log('连接已关闭');
};
// 监听错误事件
sse.onerror = function (event) {
console.error('连接出错');
};
} else {
alert('您的浏览器不支持SSE');
}
</script>
</body>
</html>
PHP 后端代码
<?php
// 关闭输出缓冲
ini_set('output_buffering', 'off');
// 清空所有当前激活的输出缓冲区
while (@ob_end_flush()) {}
// 设置HTTP响应头
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);
echo "data: $number\n\n";
// 刷新缓冲区,将内容发送到客户端
ob_flush();
flush();
// 模拟快速响应,暂停1毫秒
usleep(1000);
}
运行示例
将上述HTML代码保存为一个HTML文件(如index.html),将PHP代码保存为sse.php。
在本地或远程服务器上配置Web服务器环境,确保PHP正常运行。
将这两个文件放置在Web服务器的根目录下。
打开浏览器访问HTML页面,即可看到服务器推送的随机数不断显示在页面上。
PHP实现中的关键点和注意事项
关闭输出缓冲:在PHP中,使用ini_set('output_buffering', 'off')和ob_end_flush()关闭输出缓冲,确保脚本输出立即发送到浏览器。
设置HTTP响应头:设置Content-Type为text/event-stream,Cache-Control为no-cache,Connection为keep-alive,X-Accel-Buffering为no,以确保服务器发送事件的实时性和连接的持久性。
消息格式:每条消息由一行或多行字段组成,字段以行为单位,每行一个字段,字段名和字段值之间以冒号分隔,字段值内容以换行符结束。消息之间以空行分隔。
刷新缓冲区:在发送消息后,使用ob_flush()和flush()刷新缓冲区,使消息立即发送到客户端。
保持连接:使用while (true)循环保持连接的持续性,确保服务器能够持续向客户端推送消息。
跨域问题:如果需要跨域,需在PHP中设置Access-Control-Allow-Origin和Access-Control-Allow-Credentials等头部信息。
结论
通过以上的PHP和HTML实现,可以成功应用SSE协议实现服务器向客户端的实时推送功能。这种技术在实时通知、实时数据更新、日志监控、进度更新等场景中具有广泛的应用价值。
打赏作者
您将是第一位评论人!