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

React Native Expo连接SignalR Hub无报错信息连接失败如何解决

React Native Expo连接SignalR Hub异常排查

问题描述

我尝试在新建的React Native Expo应用中连接我的SignalR Hub,但一直报错,且错误没有附带任何数据,无法确定错误类型。

相关代码与环境

客户端Expo代码

import { StatusBar } from 'expo-status-bar';
import React from 'react';
import { StyleSheet, Text, View } from 'react-native';
import { HubConnectionBuilder, LogLevel } from '@microsoft/signalr';

const connection = new HubConnectionBuilder()
  .withUrl('https://my-app.com/test-chat')
  .configureLogging(LogLevel.Information)
  .build();

async function start() {
  debugger;
  try {
    await connection.start();
    debugger;
    console.log('SignalR Connected.');
  } catch (err) {
    debugger;
    console.log(err);
    setTimeout(start, 5000);
  }
}

connection.onclose(async () => {
  await start();
});

// Start the connection.
start();

export default function App() {
  return (
    <View style={styles.container}>
      <Text>Hello World!</Text>
      <StatusBar style="auto" />
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: '#fff',
    alignItems: 'center',
    justifyContent: 'center',
  },
});

使用的SignalR前端包版本:@microsoft/signalr": "^5.0.9"

服务端Hub代码

public class TestChat : Hub
{
    public override async Task OnConnectedAsync()
    {
        var connectionId = Context.ConnectionId;

        await Groups.AddToGroupAsync(connectionId, "test-chat");
        await base.OnConnectedAsync();
    }

    public override async Task OnDisconnectedAsync(Exception exception)
    {
        var connectionId = Context.ConnectionId;

        await Groups.RemoveFromGroupAsync(connectionId, "test-chat");
        await base.OnDisconnectedAsync(exception);
    }

    public async Task Send(string message)
    {
        await Clients.Groups("test-chat").SendAsync("new_message", message);
    }
}

错误截图

控制台截图

自行排查记录

  • 本地调试模式、Web端实际应用连接均失败,最初以为移动端不需要CORS配置,排除过CORS问题
  • 补充信息1:使用了Azure SignalR服务,客户端仍然配置的是ASP.NET Core后端的Hub地址
  • 补充信息2:已经排查到第一个问题是CORS配置缺失,Windows上用安卓模拟器测试时需要将http://localhost:19000加入允许源列表;核心问题是Azure SignalR服务导致连接失败,停用Azure SignalR、直接走ASP.NET Core后端处理连接时功能正常

解决方案

结合你给出的信息,两个问题的完整修复方案如下:

  • CORS配置修正
    Expo调试模式下的JS代码运行在WebView容器中,遵循浏览器同源策略,安卓模拟器访问本地调试服务时会触发跨域校验,除了将http://localhost:19000加入允许源列表外,还要额外开启凭证允许,SignalR连接需要携带身份凭证,服务端CORS配置示例:
    // .NET 5 Startup.cs 配置
    public void ConfigureServices(IServiceCollection services)
    {
        services.AddCors(options =>
        {
            options.AddPolicy("SignalRCors", policy =>
            {
                policy.WithOrigins("http://localhost:19000")
                      .AllowAnyHeader()
                      .AllowAnyMethod()
                      .AllowCredentials();
            });
        });
        services.AddSignalR();
        // 其他服务配置
    }
    
    public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    {
        // 注意CORS中间件要放在路由、SignalR中间件之前
        app.UseCors("SignalRCors");
        app.UseRouting();
        app.UseEndpoints(endpoints =>
        {
            endpoints.MapHub<TestChat>("/test-chat");
        });
    }
    
  • Azure SignalR服务适配
    使用Azure SignalR时不能直接用原生SignalR的连接逻辑,需要做两处适配:
    1. 服务端安装对应版本的Microsoft.Azure.SignalR NuGet包,在ConfigureServices中添加Azure SignalR注册:
    services.AddSignalR().AddAzureSignalR("你的Azure SignalR服务连接字符串");
    
    1. 确认Azure SignalR服务的网络访问策略开放了你后端服务的公网出口IP,同时前端包版本和后端.NET版本保持大版本一致,避免协议协商失败。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.04 10:48:00