前言
在现代 Web 开发中,实时通信已经成为了一种非常重要的技术。随着用户的数量增加,系统的并发量也会逐渐增加。这时候,一些实时通信技术就会被引入,SSE 就是其中一种。
SSE(Server-Sent Events)是一种基于 HTTP 协议的服务器推送技术,在前端应用中得到了广泛的应用,比如在线聊天室、股票行情等实时更新的应用场景。SSE 从服务器向客户端发送单向实时数据流,通过持久连接的技术,实现了服务器对客户端的主动通知,将更快地向前端推送实时数据。
本文将会探讨如何在大型系统中,使用 SSE 技术来支持高并发。
SSE 的优势
相比其他实时通信技术,SSE 有以下几个优势:
- SSE 是基于已有的 HTTP 协议而构建的,不需要额外开启端口或协议,对服务器端架构无任何要求,转发和代理等方式都通用;
- SSE 可以保持长连接,从而避免 HTTP 报头和链接的开销,减轻服务器压力;
- SSE 提供了更加灵活、简洁的消息格式,从而可以避免一些繁琐的 JSON 报文解析工作;
- SSE 可以回传文本、JSON 以及二进制文件,具有很好的扩展性。
SSE 的实现原理
在 SSE 的实现中,服务器将数据封装成特定格式的消息(通常是文本格式),通过已经建立好的连接将消息一次次地推送给客户端。这里的连接并不是长时间保持不断的,而是保持一定时间(建议为一分钟以内)然后在客户端断开连接后,服务器在一定时间内重新建立连接,从而推送新的消息。
客户端在接收到数据后,需要通过 JavaScript 处理,根据消息类型更新页面相关展示。
SSE 主要由以下那三个部分组成:
- 事件类型:事件类型是一个关键字,用于告诉浏览器该事件的类型。在浏览器端,可以使用 onmessage() 事件处理程序来监听该事件。
- 数据:是推送到浏览器的消息正文,是一个字符串,可以用文本、JSON、XML等格式来传递。
- 回退重连时间:告诉浏览器执行连接失败时的连接重试的功能,在没有指定的情况下,浏览器会在三秒钟后自动重连。
SSE 超出并发的问题
在大型系统中,当并发量超过一定限制时,SSE 技术也可能会出现一些问题:
- 浏览器硬件环境的限制:每个浏览器在处理文本、JavaScript 等资源时都存在一定的瓶颈,当服务器向浏览器发送大量 SSE 数据时,可能会导致浏览器无法承受超过一定量的 SSE 数据。
- 服务器的潜在问题:SSE 技术中的持久连接,也给服务器带来了压力,如果服务器无法承受大量的长连接或高并发,可能导致服务器崩溃或性能下降。
针对以上问题,以下是一些针对大型系统的 SSE 最佳实践:
SSE 通信模型
为了解决 SSE 通信模型的问题,我们可以使用分布式服务器的方式进行实现。将不同的消息推送到不同的服务器,并跟踪每个客户端从何处接收其消息。这个通信模型主要由三个部分组成:
- 数据源:数据源组件是服务器或服务,它生成更新并将其推送到消息服务器。
- 消息服务器:经过中间件展现的消息服务器,维护客户端和数据源之间的联系,并负责将数据推送到正确的客户端。如果到客户端的连接断开,消息服务器会根据需要重新连接,这时数据源就可以推送新的数据。
- 客户端:客户端需要连接到消息服务器,以便能够准确地接收消息,必要时重新连接。
SSE 广播优化
在实践中,我们需要对 SSE 的广播进行优化。可以将广播分成三类,不同类别的广播有不同的优化方案。
广播类型一:基于全选字段广播
基于全选字段广播可以使用策略来避免重复发送广播。即服务器端根据现有数据界面检查广播是否需要发送,只有在需要发送广播的情况下才会向客户端发送数据。
广播类型二:选择性广播
更为复杂的广播可以使用有选择性的方法,服务器不将广播发往所有客户端,而是仅针对指定的客户端进行广播。这种广播的好处在于,可以避免服务器向未连接的客户端发送广播。
广播类型三:实时广播
实时广播主要针对非常实时的广播。这种广播方式要求服务器向客户端发送最新数据,因此可以使用 Delta 或 Diff 消息等技术来减少传输的数据量,提高传输速率。
示例代码
以下是一个使用 SSE 技术实现的聊天室示例代码:
服务端代码:
----- ---- - ---------------- ----- -- - -------------- ----- --- - --------------- ----- ----------- - ----------------------- ----- ----- - --------------- --- - --------- - ----------------------- -- ----- -------- -------------- --------------- - --- - ---- ----------- -------------------------- -------------------- - --- - ------------------------------ - ------ ------------ --- -------- - --------------------- --- ----- - --------------------- ------------------------- - ---- ------------------ --- --------- - --------------------- -------------- -------------------------- --- ---------------------------- --- - - - -- ------- --- ---------- - ------------------------------ --- ---------- - ------------------- --- - ----------------- -- ------- ---- ---- --------------------------------------------- ------ -- ---- ---- ----------- --- ------ - --- ------------------- -- -------------------- ------------------ --- ------------------ - ------------------------------ ---------------------------------------------------------------- ------------------- --- ------ -- ----- ---- ------------- --- -- - ------ ------------------- ----------------------------------- --------------------------- ------------------------- --- --- -------- - --- --- --- ---- - -------------------- ------------------------------------------------------- - -------------------------------- ------------------------------- --------------------------------- --- ------ -------- ------------ --- ---- -------------- ------ - - ----- ------- - --------------- ------ ----------- - --- ----- -------- - --- ---------- ------------------------
客户端代码:
------ ------ -------- -------- ---------- --- ------- - ----------------------------------------------- --- -------- - ------------------------------------------------ ------------------ -------------- --------- --------------------------------- -- ----- ---------------- ---------------- -- ---------------- --- ------------------ --- ----- ---------------------------------------------- - --- - -- - --- ----------- - --- -------------------------- --------------------- - ---- --- ------- - ------------------- --- --------- - --------------------------------------------- --- -- - ----------------------------- ------------ - ----------------------------------------- -------------------------- - --------- ------- ------ ------------ --- ---------------------------- ---- --------------------- ------ ------------------- ------------ ------ ------------------ ------------ ------- ------------------------------- ------ ------- -------
结论
通过实践,我们可以发现,在大型系统中,SSE 技术可以通过增加服务器负载和优化 SSE 广播等方式来有效地支持高并发。同时,SSE 技术可扩展和灵活,可以适用于很多实时通信开发场景。
来源:JavaScript中文网 ,转载请注明来源 本文地址:https://www.javascriptcn.com/post/67316e900bc820c58238cb6e