服务器发送事件(SSE)是一种基于 HTTP 协议的单向通信协议,它允许服务器以事件流(Event Stream)的形式实时向客户端推送数据,而无需客户端明确请求。它建立在标准的 HTTP 协议之上,通过单向的持久连接,服务器可以主动向客户端发送事件和数据。
本质上,它是以流信息的方式来实现的,由客户端向服务端发起建立连接请求,并保持连接打开,然后服务端主动推送消息给客户端,服务器给客户端发送的 SSE 数据,必须是 UTF-8 编码,且返回的内容类型是 text/event-stream。
比如当你在使用 ChatGPT 时,当你询问它问题时,你会看到它会逐字地将回答显示出来,实际上这是 ChatGPT 将先计算出的数据主动的“推送”给你,采用 SSE 技术边计算边返回,避免接口等待时间过长而直接关闭页面。
实时性:SSE 提供了一种实时通信机制,允许服务器主动向客户端推送数据。这种实时性使得 SSE 特别适用于需要即时更新的应用场景,如实时聊天、在线协作工具、实时数据展示、通知推送等。
减少网络负担:与传统的轮询方式相比,SSE 采用长连接,通过单一的 HTTP 连接,服务器可以向客户端推送多个事件,避免了频繁的 HTTP 请求,从而减少了网络负担。
轻量级:SSE 是基于 HTTP 协议,现有的服务器软件都支持,相较于 WebSocket,SSE 的使用更加简单。
自动重连:SSE 在连接中断后能够自动尝试重新建立连接,而无需额外的代码。这种自动重连机制增加了系统的稳定性,确保即使在网络不稳定的情况下,通信仍能够持续进行。
在实际应用中,利用 API 网关代理 SSE 服务有助于提升服务的稳定性,解决安全和跨域问题,适用于处理复杂的应用场景。NGINX 作为最受欢迎的反向代理服务器之一,市场份额颇高。在 NGINX 上代理 SSE 服务时,需要禁用 proxy_buffering。然而,这种配置至少要在 location 级别进行关闭,这意味着如果系统中存在多个 location,仅有少数需要关闭缓存以支持 SSE 服务时,可能会影响其他非 SSE 的 API 的性能。此外,NGINX 的 proxy_buffering 配置缺乏灵活性,无法在运行时动态启用或禁用,需要通过重新加载配置来生效,这可能会导致服务中断。
API7 企业版提供了 proxy-buffering 插件,让您能更灵活地代理 SSE 上游服务。通过在相应的路由中启用该插件,您可以轻松控制缓存的开关,而无需重新加载整个配置。这种灵活性既能满足 SSE 服务的代理需求,又兼顾性能和动态配置的要求。
通过测试可以看到已经成功代理了 SSE 服务。
1 | curl "http://127.0.0.1:9080/.sse" -H "Accept: text/event-stream" |
总体而言,SSE 适用于需要实时通信和更新的场景,它提供了一种简单而有效的方式。但是需要注意 SSE 是一种单向通道,只能由服务器向客户端发送消息,所以 SSE 并不适用于所有类型的实时通信需求。对于更复杂的双向通信场景,可以考虑使用 WebSocket 等其他技术。