如何配置Mercure连接订阅数?EventSource多标签页连接Pending问题求助
解决Mercure多标签页下连接Pending问题
问题根因
现代浏览器对同一域名的持久HTTP长连接(EventSource默认使用的就是这类连接)有并发数限制,Chrome等主流浏览器默认上限是6个。所以打开第6个标签页时,新的连接会被浏览器拦截排队,进而出现Pending状态。
具体解决配置方案
1. 开启HTTP/2突破连接限制
Mercure支持HTTP/2协议,它能在单个TCP连接上多路复用多个请求,直接绕过浏览器的6连接限制。
- Docker启动Mercure时,添加以下环境变量开启HTTP/2,同时需要配置SSL证书(HTTP/2通常依赖HTTPS,本地开发可使用自签名证书):
docker run -e MERCURE_ENABLE_HTTP2=1 -e MERCURE_CERT_FILE=/path/to/your/cert.pem -e MERCURE_KEY_FILE=/path/to/your/key.pem ...其他启动参数 dunglas/mercure
2. 调大Mercure的连接上限
默认Mercure的最大连接数可能偏小,直接通过环境变量调高即可:
docker run -e MERCURE_MAX_CONNECTIONS=1000 ...其他启动参数 dunglas/mercure
另外可以设置闲置连接超时,自动回收无用连接避免资源浪费:
docker run -e MERCURE_READ_TIMEOUT=300 ...其他启动参数 dunglas/mercure
(300为秒数,可根据自身业务场景调整)
3. 客户端用SharedWorker共享连接
多个标签页没必要各自建立独立连接,用SharedWorker创建一个全局共享连接,所有标签页通过它接收消息,整个浏览器仅占用1个连接。示例代码:
- 编写
shared-worker.js文件:
let eventSource; const clientPorts = new Set(); self.onconnect = (e) => { const port = e.ports[0]; clientPorts.add(port); // 首次连接时初始化EventSource if (!eventSource) { eventSource = new EventSource('你的Mercure服务URL'); eventSource.onmessage = (event) => { // 将消息分发给所有连接的标签页 clientPorts.forEach(p => p.postMessage(event.data)); }; } // 监听客户端关闭,清理资源 port.onclose = () => { clientPorts.delete(port); if (clientPorts.size === 0) { eventSource.close(); eventSource = null; } }; port.start(); };
- 在页面中调用这个SharedWorker:
const worker = new SharedWorker('shared-worker.js'); worker.port.onmessage = (event) => { console.log('publishEventFromTopic', event.data); }; worker.port.start();
4. 反向代理层优化(以Nginx为例)
如果用Nginx作为Mercure的反向代理,记得开启HTTP/2,同时配置长连接相关参数:
server { listen 443 ssl http2; server_name 你的域名; ssl_certificate /path/to/cert.pem; ssl_certificate_key /path/to/key.pem; location /.well-known/mercure { proxy_pass http://你的Mercure容器地址:3000; proxy_set_header Host $host; proxy_set_header X-Forwarded-For $remote_addr; proxy_set_header X-Forwarded-Proto $scheme; # 启用HTTP/1.1长连接 proxy_http_version 1.1; proxy_set_header Connection ""; # 关闭缓冲,适配EventSource流式响应 proxy_buffering off; proxy_cache off; } }
内容的提问来源于stack exchange,提问作者Den Step
相关产品推荐
相关产品推荐

