办公设备维修网
资讯中心 您所在的位置:网站首页 资讯中心 解决EventSource触发的浏览器并发量限制问题

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

2024-06-26 13:25:44| 来源: 网络整理

文章目录 问题描述原因分析可用方案改用WebSocket (推荐方案)基于SharedWorker的客户端SSE共享方法[次推荐方案]客户端多页面复用同一个SSE的其他方法服务端主动将连接降级改用HTTP/2.0协议 总结 问题描述

浏览器对同一域名下的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方案的场景一般遇不到此类问题, 且多数情况下不会同时打开很多的页面窗口. 解决起来也没有很直接的方案, 客户端或服务端改造点比较多.



【本文地址】 转载请注明 

最新文章

推荐文章

CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备16040606号-1