SignalR连接数受限引发Axios请求Pending状态问题求助
问题分析与解决方案
核心问题根源
- SignalR连接数超限:每次调用
getUpcomingLots都会新建一个SignalR连接,浏览器对同一域名的HTTP/1.1并发连接数默认有上限(通常3-6个),重复创建连接会快速耗尽连接池,导致无法建立新连接。 - Axios请求排队:SignalR的长连接占用了所有可用并发连接,浏览器会将Axios的HTTP请求放入队列,直到有连接释放(如其他用户刷新页面关闭连接)才能执行,因此出现Pending状态。
前端代码修复(React端)
1. 复用SignalR连接,避免重复创建
将SignalR连接实例用useRef维护,仅在组件初始化时创建一次,组件卸载时关闭连接:
import { useEffect, useRef, useState } from 'react'; import * as signalR from '@microsoft/signalr'; import axios from 'axios'; // 组件内代码 const hubConnectionRef = useRef<signalR.HubConnection | null>(null); const [upcomingLots, setUpcomingLots] = useState<any[]>([]); const [loading, setLoading] = useState(false); useEffect(() => { // 仅在连接不存在时初始化 if (!hubConnectionRef.current) { const connection = new signalR.HubConnectionBuilder() .withUrl(HUBURL, { withCredentials: false, // 移除无效的请求头:Cross-Origin-Resource-Policy是服务器响应头,客户端设置无意义 }) .withAutomaticReconnect() .build(); // 监听服务器推送的消息 connection.on("SendUpcomingLots", (data: any) => { setUpcomingLots(data); }); // 启动连接 connection.start().catch(err => console.error('SignalR连接失败:', err)); hubConnectionRef.current = connection; } // 组件卸载时关闭连接 return () => { hubConnectionRef.current?.stop().catch(err => console.error('SignalR关闭失败:', err)); hubConnectionRef.current = null; }; }, []);
2. 分离Axios请求与SignalR连接逻辑
getUpcomingLots仅负责数据请求,不再创建SignalR连接:
const getUpcomingLots = async () => { setLoading(true); try { await axios.get(`${APIURL}?auctionId=${ID}&customerId=${customerId}`); setLoading(false); } catch (error) { console.log("APIURL Error Send", new Date()); setLoading(false); } };
服务器端配置检查(以ASP.NET Core为例)
- 调整SignalR连接上限:在
Program.cs中设置允许的最大并发连接数:
builder.Services.AddSignalR(options => { // 根据业务需求设置,支持上万用户可设为10000+ options.MaxConcurrentConnections = 10000; });
启用HTTP/2:HTTP/2支持多路复用,突破HTTP/1.1的并发连接数限制,大幅提升连接承载能力。确保服务器部署时启用HTTP/2(如IIS、Nginx均支持)。
反向代理WebSocket配置:若使用Nginx等反向代理,需配置WebSocket转发,否则SignalR无法正常建立长连接:
location /your-hub-path { proxy_pass http://your-backend-server; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; proxy_set_header Host $host; }
验证步骤
- 测试前端:多次刷新页面或打开多个标签页,检查SignalR连接是否仅创建一次,Axios请求是否立即返回。
- 压测验证:模拟大量用户连接,确认连接数不再受限,实时更新功能正常。
内容的提问来源于stack exchange,提问作者Pankaj Mundra
相关产品推荐
相关产品推荐

