# Server-Send-Event

想从服务端进行数据推送的话有哪些方案呢?

以前我只知道有WebSocket

最近在搞AI,大模型在生成回复的时候都是实时推送的,今天自己了解了下,原来用的是Server-Send-Event方案。

# Server-Send-Event

Server-Sent-EventsSSE)是一种HTML5 API,用于在服务器和客户端之间实时推送数据流。 它基于HTTP协议,通过建立一个持久连接,服务器可以推送消息给客户端,而无需客户端发起请求。 这使得服务器可以实时向客户端发送数据,而不需要客户端轮询服务器。SSE可以用于实现实时通知、实时聊天、实时数据更新和实时监控等功能。

# 技术上:

  1. SSE是基于HTTP长连接实现的,由客户端发起一次请求,服务器端保持连接打开,随时可以向客户端推送数据,直到客户端关闭连接。

  2. SSE使用的是text/event-stream MIME类型,服务器端通过这个MIME类型告诉客户端它将发送一系列事件流。

  3. 服务器可以发送多个事件流,每个事件流以event关键字开始(如果没有event字段则前端只能通过onmessage监听 ), 数据字段以data关键字开始,并以一个换行符结束。整个事件流以连续两个换行符结束。

  4. 服务器可以发送一个retry字段,用来指定在连接断开后重新连接的时间间隔。

event: ${eventName}
id: 1
retry: 5000
data: ${dataString}

  1. 客户端通过EventSource API接收SSE

# DEMO

源码

在线 DEMO

SSE 前端

# 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

如果需要使用nginxServer-Send-Events进行反向代理的话,需要进行如下额外配置:

proxy_http_version 1.1;
proxy_set_header Connection "";
proxy_buffering off;

# 参考

  1. Server-sent events
  2. EventSource
  3. Server-Sent Events: пример использования
  4. Nginx proxy for SSE
最后更新: Sun, 13 Aug 2023 05:10:56 GMT

0 评论

加载中...
访问量:-