You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React中SignalR客户端连接报错:传输方式被客户端禁用

问题分析与解决

什么是“被客户端禁用”?

这个错误是SignalR JS客户端在尝试建立连接时,发现所有指定/可用的传输方式均无法正常使用(比如连接请求失败、环境不支持等),从而判定这些传输方式“被客户端禁用”——本质是客户端无法通过任何传输方式完成连接,并非真的被主动禁用。

可能的原因及解决办法

1. AccessToken 异步处理错误

你的getUserAccessToken如果是异步函数(比如调用了fetch或使用async/await),直接返回会得到一个Promise而非实际的token值,导致SignalR请求因认证失败被服务器拒绝,进而触发传输方式不可用的错误。

修正方式:
确保accessTokenFactory正确处理异步逻辑:

options.accessTokenFactory = async () => await getUserAccessToken();

同时可以在控制台打印getUserAccessToken的返回值,确认是否能获取到有效的JWT token:

// 在useEffect中临时测试
useEffect(() => {
  const checkToken = async () => {
    const token = await getUserAccessToken();
    console.log("获取到的Token:", token);
  };
  checkToken();
}, []);

2. 传输方式配置冲突

你当前设置了options.transport = HttpTransportType.WebSockets但skipNegotiation=false,这会导致客户端先发起协商请求,再强制使用WebSocket传输,可能引发冲突。

修正方式:
如果要强制使用WebSocket,需开启skipNegotiation跳过协商步骤:

options.skipNegotiation = true;
options.transport = HttpTransportType.WebSockets;

如果不需要强制指定传输方式,直接移除transport配置,让客户端自动协商选择最优传输:

// 移除 options.transport = ... 这一行
options.skipNegotiation = false; // 默认值,可省略

3. CORS 配置缺失关键项

虽然C#客户端正常,但JS客户端需要CORS允许携带凭证(Credentials),否则SignalR连接会被拦截。

后端CORS配置补充:
确保.NET后端的CORS策略包含AllowCredentials():

builder.Services.AddCors(options =>
{
    options.AddPolicy("AllowReactApp", policy =>
    {
        policy.WithOrigins("http://localhost:3000") // 替换为你的React应用地址
              .AllowAnyHeader()
              .AllowAnyMethod()
              .AllowCredentials(); // 必须添加此项
    });
});

// 中间件中启用CORS
app.UseCors("AllowReactApp");

4. 检查浏览器网络请求

打开浏览器开发者工具(F12)→ Network标签,过滤WebSocket或XHR请求,查看SignalR的协商请求(negotiate)、WebSocket连接请求的状态码:

  • 如果是401 Unauthorized:说明token无效或未正确传递,回到第一步排查token获取逻辑
  • 如果是403 Forbidden:检查后端Hub的授权策略是否允许当前用户连接
  • 如果是500 Internal Server Error:查看后端日志定位服务器端异常

修正后的完整示例代码

import { HubConnectionBuilder, LogLevel, HttpTransportType } from '@microsoft/signalr';
import { getUserAccessToken } from '../auth/UserManager';

export function ConnectToSignalR(){
   return new HubConnectionBuilder()
        .withUrl('http://localhost:18198/messagehub', async options => {
            options.accessTokenFactory = async () => await getUserAccessToken();
            // 强制WebSocket传输
            options.skipNegotiation = true;
            options.transport = HttpTransportType.WebSockets;
            return options;
        })
        .withAutomaticReconnect()
        .configureLogging(LogLevel.Trace)
        .build();
}

export function startSignalRConnection(signalRConnection){
    if (signalRConnection) {
        signalRConnection.start()
              .then(result => {
                  console.log('SignalR','Connected!');

                  signalRConnection.on('TimeWarningMessage', message => {
                     console.log(message);
                  });
              })
              .catch(e => console.log('SignalR Connection failed: ', e));
            }
}

内容的提问来源于stack exchange,提问作者Ni9e

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.20 15:43:17