解决EventSource触发的浏览器并发量限制问题

文章讨论了浏览器对同一域名的HTTP并发连接数限制如何影响SSE(EventSource)的使用,导致并发问题。推荐的解决方案是改用WebSocket,因为它不占用HTTP连接限制。次优方案是利用SharedWorker在客户端共享SSE连接。此外,还提到了通过服务端主动降级连接为短轮询和使用HTTP/2.0协议来避免问题。
摘要由CSDN通过智能技术生成

问题描述

浏览器对同一域名下的HTTP/HTTPS (1.0和1.1下)有并发数限制, 比如chrome并发数为6, 超过该数量后, 新的请求会加入到请求队列中等待. 而EventSource实质上是一个一直不关闭的HTTP请求, 所以会占用一个连接数. 这就导致了一个可用并发数的减少. 假设一个页面中有一个SSE连接, 则当打开六个tab页面或窗口时, 连接数占满; 而第七个页面的所有请求都被加入到等待队列中, 导致第七个页面以及前六个页面中新的ajax请求无法正常发出, 页面卡死.

原因分析

  • SSE(EventSource) 持续占用一个可用连接
  • 浏览器连接数量限制不易修改或不方便修改

可用方案

改用WebSocket (推荐方案)

WebSocket不会占用HTTP并发限制数量, 且单个域名下WebSocket连接数的限制比较大(chrome为256), 改用WebSocket可以解决并发占用问题.

限制: 个别网络情况下不支持ws://协议时该方案不可用.

基于SharedWorker的客户端SSE共享方法[次推荐方案]

SharedWorker可以实现与多个页面间的直接消息转发,且会在所有页面关闭后自动销毁,很契合当前的应用场景。
页面启动时new SharedWorker()创建/复用一个Worker对象, Worker对象启动时创建SSE;

页面2
页面1
SharedWorker
创建SharedWorker
页面2初始化
页面2收到消息
得到页面间消息通道
创建SharedWorker
页面1初始化
页面1收到消息
得到页面间消息通道
等待SSE消息
使用SSE
创建SSE
初始化Worker
SharedWorker已实例化
注册消息

客户端多页面复用同一个SSE的其他方法

通过浏览器客户端技术复用连接,降低并发数量, 见#基于SharedWorker的客户端连接共享方法
通过本地广播+心跳+抢占主页面身份实现推动持续可用

具体需要的技术思路:

  • [推荐]使用浏览器端的SharedWorker实现多页面共享相同连接,SSE由SharedWorker发出并将消息转发到各页面,详见后面小节
  • 记存在实际SSE连接的页面为主页面,其他页面为从页面
  • 主页面结束本浏览器的所有请求(依赖于客户端id)
  • 通过页面间通讯实现主到从的本地消息广播
    • 可以选用postMessage()
    • 也可以选用localStorage+StroageEvent
  • 主页面定时器发送心跳; 从页面启用计时器轮询监听心跳
  • 从页面发现心跳超时后主动抢占主页面所有权并创建新的SSE

服务端主动将连接降级

服务端发现来自同一个浏览器的SSE连接数量大于5以后, 主动将所有连接降级为短轮询
发现同一浏览器的短轮询页面数量小于4以后,逐步恢复为SSE
客户端不做改造, 改造均在服务端, 通过服务端主动关闭并通知客户端重连的方式进行

具体的技术思路:

  • 服务端维持连接数组并记录来自的客户端id和页面id
  • 维护一个10s内所有消息的缓存池, 新消息都存储到池中
  • 并发量大于5时, 在发送完待推送的消息后, 服务端下发retry为1000并主动关闭连接; 此时新的SSE建立后从缓存池中查询有没有该链接需要的消息, 有则直接推送,没有则推送空消息; 下发retry:1000, 并主动关闭连接

该方案实质上是在识别出连接数将要受限时, 降级成短轮询, 用牺牲推送实时性的方式保证有效性. 此方案也可以改造为长轮询解决部分问题.(降级为长轮询控制复杂度会更高些,需要考虑retry时间间隔的精确控制)

改用HTTP/2.0协议

HTTP2.0下使用了多路复用, 客户端不存在连接限制; 改用H2后不存在类似问题, 也不需要解决;

该方案需要环境配置支持, 包含上游转发层和中间件

总结

该问题相对冷门, 因为能使用WebSocket方案的场景一般遇不到此类问题, 且多数情况下不会同时打开很多的页面窗口. 解决起来也没有很直接的方案, 客户端或服务端改造点比较多.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值