React应用连接Azure SignalR遇FailedWritingMessageToServiceException问题求助
问题解决方案
一、Azure SignalR服务下的FailedWritingMessageToServiceException报错处理
1. 验证Azure SignalR配置正确性
- 确认使用的是Azure Portal中SignalR服务的主连接字符串,不要手动拼接或使用错误密钥。
- 检查SignalR服务定价层:免费层存在连接数和消息量限制,高频率调用易触发写入失败,建议切换到标准层。
- 检查SignalR服务的网络防火墙设置,确保你的.NET Core API服务器IP被允许访问。
2. 修正客户端连接配置
使用Azure SignalR时不能跳过协商步骤,强制跳过会导致客户端无法正确路由到Azure的SignalR节点,修改客户端代码:
try { const connection_ = new HubConnectionBuilder() .withUrl("https://localhost:44368/hubs") .withAutomaticReconnect() .configureLogging(LogLevel.Information) .build(); connection_.on("DataReceived", (x, y, z) => { setData(prev => ({ ...prev, x: x, y: y, z: z })); }); await connection_.start(); await connection_.invoke("GetData", location.state.id); } catch(e) { console.log(e); }
3. 排查GetData方法异常
在服务端的SensorHub中给GetData方法添加详细日志,确认是否是业务逻辑抛出异常导致消息写入失败:
private readonly ILogger<SensorHub> _logger; public SensorHub(ILogger<SensorHub> logger) { _logger = logger; } public async Task GetData(string id) // 确保参数类型和客户端传递的一致 { try { // 你的业务逻辑代码 await Clients.Caller.SendAsync("DataReceived", x, y, z); } catch (Exception ex) { _logger.LogError(ex, "执行GetData时出错,ID:{Id}", id); throw; // 抛出异常让客户端接收明确错误信息 } }
二、移除Azure SignalR后250次连接后自动断开的问题处理
1. 调整Kestrel和SignalR连接限制
在Program.cs中增加Kestrel的并发连接限制,同时优化SignalR的超时配置:
builder.WebHost.ConfigureKestrel(options => { options.Limits.MaxConcurrentConnections = 1000; // 根据业务需求调整 options.Limits.MaxConcurrentUpgradedConnections = 1000; }); services.AddSignalR(hubOptions => { hubOptions.EnableDetailedErrors = true; hubOptions.KeepAliveInterval = TimeSpan.FromMinutes(1); // 缩短心跳间隔,维持连接活跃 hubOptions.ClientTimeoutInterval = TimeSpan.FromMinutes(3); // 延长客户端超时时间 hubOptions.MaximumReceiveMessageSize = 1024 * 1024; // 若消息较大,调大此值 });
2. 客户端连接资源清理
确保组件卸载时关闭旧连接,避免连接堆积耗尽服务器资源:
useEffect(() => { let connection_; const connect = async () => { try { connection_ = new HubConnectionBuilder() .withUrl("https://localhost:44368/hubs", { skipNegotiation: true, transport: HttpTransportType.WebSockets, }) .withAutomaticReconnect() .configureLogging(LogLevel.Information) .build(); connection_.on("DataReceived", (x, y, z) => { setData(prev => ({ ...prev, x, y, z })); }); await connection_.start(); await connection_.invoke("GetData", location.state.id); } catch (e) { console.log(e); } }; connect(); // 组件卸载时关闭连接 return () => { if (connection_) { connection_.stop().catch(err => console.error("关闭连接失败:", err)); } }; }, [location.state.id]); // 依赖location.state.id,ID变化时重建连接
3. 查看服务器详细日志
在appsettings.json中开启SignalR的Debug级别日志,排查断开原因:
{ "Logging": { "LogLevel": { "Default": "Debug", "Microsoft.AspNetCore.SignalR": "Debug", "Microsoft.AspNetCore.Http.Connections": "Debug" } } }
内容的提问来源于stack exchange,提问作者Mahesh205619
相关产品推荐
相关产品推荐

