# Server-Send-Event
想从服务端进行数据推送的话有哪些方案呢?
以前我只知道有WebSocket
最近在搞AI
,大模型在生成回复的时候都是实时推送的,今天自己了解了下,原来用的是Server-Send-Event
方案。
# Server-Send-Event
Server-Sent-Events
(SSE
)是一种HTML5
API
,用于在服务器和客户端之间实时推送数据流。
它基于HTTP
协议,通过建立一个持久连接,服务器可以推送消息给客户端,而无需客户端发起请求。
这使得服务器可以实时向客户端发送数据,而不需要客户端轮询服务器。SSE
可以用于实现实时通知、实时聊天、实时数据更新和实时监控等功能。
# 技术上:
SSE
是基于HTTP
长连接实现的,由客户端发起一次请求,服务器端保持连接打开,随时可以向客户端推送数据,直到客户端关闭连接。SSE
使用的是text/event-stream
MIME
类型,服务器端通过这个MIME
类型告诉客户端它将发送一系列事件流。服务器可以发送多个事件流,每个事件流以
event
关键字开始(如果没有event
字段则前端只能通过onmessage
监听 ), 数据字段以data
关键字开始,并以一个换行符结束。整个事件流以连续两个换行符结束。服务器可以发送一个
retry
字段,用来指定在连接断开后重新连接的时间间隔。
event: ${eventName}
id: 1
retry: 5000
data: ${dataString}
- 客户端通过
EventSource
API
接收SSE
。
# DEMO
# PHP 代码
date_default_timezone_set("America/New_York");
header("Cache-Control: no-store");
header("Content-Type: text/event-stream");
$counter = rand(1, 10);
while (true) {
// Every second, send a "ping" event.
echo "event: ping\n";
$curDate = date(DATE_ISO8601);
echo 'data: {"time": "' . $curDate . '"}';
echo "\n\n";
// Send a simple message at random intervals.
$counter--;
if (!$counter) {
echo 'data: This is a message at time ' . $curDate . "\n\n";
$counter = rand(1, 10);
}
ob_end_flush();
flush();
// Break the loop if the client aborted the connection (closed the page)
if (connection_aborted()) break;
sleep(1);
}
# nginx 代理 Server-Send-Events
如果需要使用nginx
对Server-Send-Events
进行反向代理的话,需要进行如下额外配置:
proxy_http_version 1.1;
proxy_set_header Connection "";
proxy_buffering off;