SSE 技巧分享:使用 nginx 推送增强性能和稳定性
随着 Web 技术的不断发展,实时性的需求越来越高。传统的 Ajax 轮询虽然可行,但却不是最好的实现方式。而对于频繁通信的场景,服务器推送(Server Push)技术则是一个更好的选择。
SSE(Server Sent Events)是一种实现服务器推送的技术,它利用了 HTTP/2 协议增加的 Server Push 功能,是一种轻量级、易于实现、浏览器兼容性良好的实时通信技术。
本文将介绍如何通过 nginx 来实现 SSE,以增强性能和稳定性。
一、为什么要使用 nginx 推送 SSE
SSE 虽然是一种很好的技术,但在实现时需要注意一些问题。例如,客户端的网络波动、较慢的网络速度、服务器的崩溃等等。这些问题都会影响 SSE 的实时性和稳定性。
而 nginx 作为一款高性能的 Web 服务器,可以帮助我们解决这些问题。它可以承担推送的任务,通过它内置的机制,可以实现客户端数据的无损推送。
二、配置 nginx 推送 SSE
- 环境搭建
在开始之前,首先需要安装 nginx、node 等环境。
可以通过源码包、官网的安装包、直接使用 yum 或 apt 等包管理工具来安装。在安装好后,可以执行以下命令检查是否安装成功。
nginx -v
node -v
- 服务器端配置
2.1. 安装必要的组件
安装完 nginx 和 node 环境后,需要安装 nginx 的 Http Push Module 和 nginx-push-stream-module。这两个模块分别用来支持服务端和客户端的 SSE 实现。
安装 Http Push Module,可以使用以下命令。
-- -------------------- ---- ------- --- -- ------ --- -- ------- --- ------- --------------- ---------- ---------- ---- ----- -------- ---- ---------------------------------------------- --- ---- ------------------- -- ------------ --- ----- ----------------------------------------------------- ----------- ---------------------------- ---- -- ---- ------- -- --
安装 nginx-push-stream-module,可以使用以下命令。
yum -y update yum -y install git git clone https://github.com/wandenberg/nginx-push-stream-module.git cd nginx-push-stream-module
2.2. 配置 nginx
接下来,需要修改 nginx 配置文件,使其支持 SSE。
在 nginx.conf 配置文件中添加以下内容:
-- -------------------- ---- ------- ---- - ------------------------------ --- -------- ------- - ------ --------------- - ------ - ------ ----- -------- ------- - --------------------- ------ ------------------------- -------- -------------------------- --- --------------------------------- --- ---------- -------------- ------------------- --------------- ---------- --------------- ----------- ----------------- ---- ------- ---- ------------------------- ---- --------------------- ----- ------------------ ------- ------------------ ------- ------------ ------- ------------------------- ---- ------------------ ---- ------------------ ------------- ---------------------- --- ---------------- --- -------------------- --- ------------------------ ---- ----------------- --- --- ----------------- --- --- ----------------- --- --- ----------------- --- --- ---------- --------------- --------------- ---- ----------- ---- ---------------- ------- -------------- ---------------- ---------- ---------- ---------------- --------------- --------------------------- ---- ---- - - -
这里添加了一个 server,监听端口为 3000,用于支持 SSE。同时需要创建一个 upstream,这个 upstream 对应的是自己的业务服务器。在实际使用中,需要更改自己应用服务器的 IP 和端口号。location /stream 对应的就是 SSE 的 URL。
push_stream_publisher 表示开启推送者的权限,可以通过推送者身份来推送消息。admin 可以在上下文范围内的每个频道中发布消息。
add_header 添加 HTTP 头,表示返回的响应是 SSE。其中,Content-Type 是 text/event-stream 类型,Cache-Control 设置为 no-cache。
在 location /stream 中,我们做一些高级的优化。例如,chunked_transfer_encoding,当将大量数据发送到客户端时,这意味着无需传输整个响应,而是将数据分成几个块进行传输。
代理超时的设置也非常关键。我们不希望代理在很短的时间内丢失掉保存数据的连接。代理连接的值可以通过这个参数配置。发出连接请求后,连接到远程主机的时间超过此值,则关闭连接。 proxy_send_timeout 和 proxy_read_timeout 配置读取和发送数据的超时时间,发送和读取的超时时间必须大于 Keep Alive 时间。
这里 gzip 设置为 off,这样可以避免浪费 CPU 资源。
引入 location /stream 设置完毕后,我们还需要将它添加到 nginx.conf 配置文件中的 http 段。
- 客户端实现
接下来是客户端的实现。SSE 是 HTML5 特性,可以通过原生 JS 调用实现。
// index.html
-- -------------------- ---- ------- --------- ----- ------ ------ ----- --------------- -- ------------- ---- -------------- ------- ------ --- --------------- -------- -------- ------ - --- ------ - --- ------------------------- - ------------- ---------------- - -------- --- - --- ---- - ------------------- --- -- - ----------------------------- ------------ - --------- - -- - - --------- ------------------------------------------------ -- - --- ----------- - ------- ------- --------- ------- -------
在 HTML 中,添加了一个 ul 标签用于展示数据。在脚本中,通过 new EventSource 创建了一个 SSE 传输。当有数据过来时,会自动调用 onmessage 函数。
三、实现效果
通过以上的配置,就可以实现服务端推送 SSE 了。
Python 代码示例(服务器端):
-- -------------------- ---- ------- - --------- ---- ----- ------ ------ ----------------------- -------- ------- ---- ---------- ------ ---- --- - --------------- --------- --------------- --- -------- ------ ----------------------- --- --------- ----- ------ ------ ----- --------------- -- ------------- ---- -------------- ------- ------ --- --------------- -------- -------- ------ - --- ------ - --- ------------------------- - ------------- ---------------- - -------- --- - --------------------- -------- - - -------- --- ---- - ------------------- --- -- - ----------------------------- ------------ - --------- - -- - - --------- ------------------------------------------------ -- - --- ----------- - ------- ------- --------- ------- ------- --- - -- -------- -- ----------- ----------------------- ---------- -----------
Node.js 代码示例(服务器端):
-- -------------------- ---- ------- -- --------- ----- ---------- - ----------------------------- ----- ------- - ------------------- ----- --- - ---------- ----- ---------- - --- ------------- ------------------------------ ------------------------ --------- -- - --------------------- -------- ------------- -------------------------- ---------------- ----- ----------- ---- ------- ---- --- --------------------- ----- ---- -- - --------------------------- -- - -------------------------- ---------------- ----- ----------- ---- ------- ---- -- ------ ----------------------------- -------------- ---------------- ---- ----------- --- ---------------- -- -- - ------------------- ----------- ---
以上代码中,从客户端事件源的 URL 触发 SSE。在启动服务端之后,通过浏览器打开 http://localhost:4000/,可以看到推送的消息,每次刷新都能看到新的消息。
四、总结
SSE 技术在浏览器端实现实时通信提供了一种简单而有效的方式。在实际应用中,可以通过配置 nginx 来增强 SSE 技术的性能和稳定性,进一步提高应用的实时性。同时,在使用 SSE 时,还需要注意身份验证、频道管理、定时脚本和数据序列化等问题,以实现更完善的实时通信功能。
来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/64e33e5cf6b2d6eab3ea6f09