.NET 6配置SignalR服务+React前端时WebSocket连接失败求助
.NET 6 SignalR 与 React 集成的正确配置(解决 WebSocket 连接失败)
一、服务器端(.NET 6)配置
1. Program.cs 核心配置
中间件顺序和SignalR服务注册是高频错误点,务必严格遵循以下顺序:
var builder = WebApplication.CreateBuilder(args); // 注册SignalR服务 builder.Services.AddSignalR(); // 配置CORS,必须匹配前端Origin、开启Credentials并允许SignalR所需头 builder.Services.AddCors(options => { options.AddPolicy("AllowReactApp", policy => { // 替换为你的React前端地址(默认http://localhost:3000) policy.WithOrigins("http://localhost:3000") .AllowCredentials() .AllowAnyHeader() .AllowAnyMethod() .WithExposedHeaders("Access-Control-Allow-Origin"); }); }); var app = builder.Build(); // 中间件执行顺序:Https重定向 → CORS → 路由 → SignalR映射 app.UseHttpsRedirection(); app.UseCors("AllowReactApp"); app.UseRouting(); // 映射ChatHub路由,路径要与前端完全一致 app.MapHub<ChatHub>("/chat"); app.Run();
2. ChatHub 实现示例
确保继承Hub类,方法符合SignalR调用规范:
using Microsoft.AspNetCore.SignalR; namespace YourProjectNamespace; public class ChatHub : Hub { // 定义客户端可调用的服务器方法 public async Task SendMessage(string user, string message) { // 向所有客户端广播消息,"ReceiveMessage"为客户端监听的事件名 await Clients.All.SendAsync("ReceiveMessage", user, message); } }
3. launchSettings.json 检查
确认服务器端口无冲突,URL配置正确:
{ "profiles": { "http": { "commandName": "Project", "dotnetRunMessages": true, "launchBrowser": true, "applicationUrl": "http://localhost:5000", // 确保此端口未被占用 "environmentVariables": { "ASPNETCORE_ENVIRONMENT": "Development" } } } }
二、React 前端配置
1. 安装依赖
npm install @microsoft/signalr
2. App.js 核心连接代码
确保URL与服务器Hub路由完全匹配,开启Credentials对应CORS设置:
import { useEffect, useState } from 'react'; import * as signalR from '@microsoft/signalr'; function App() { const [connection, setConnection] = useState(null); const [user, setUser] = useState(''); const [message, setMessage] = useState(''); const [messages, setMessages] = useState([]); useEffect(() => { // 创建SignalR连接,启用自动重连 const newConnection = new signalR.HubConnectionBuilder() .withUrl('http://localhost:5000/chat', { // 与服务器MapHub路径完全一致 withCredentials: true }) .withAutomaticReconnect() .build(); setConnection(newConnection); }, []); useEffect(() => { if (connection) { // 启动连接 connection.start() .then(() => console.log('SignalR连接成功')) .catch(err => console.error('连接失败:', err)); // 监听服务器推送的消息 connection.on('ReceiveMessage', (user, message) => { setMessages(prev => [...prev, { user, message }]); }); // 处理连接断开 connection.onclose(() => { console.log('连接断开,正在尝试重连...'); }); } }, [connection]); // 发送消息到服务器 const sendMessage = async () => { if (connection && user && message) { await connection.invoke('SendMessage', user, message); setMessage(''); } }; return ( <div className="App"> <input placeholder="用户名" onChange={(e) => setUser(e.target.value)} /> <input placeholder="消息" value={message} onChange={(e) => setMessage(e.target.value)} /> <button onClick={sendMessage}>发送</button> <div> {messages.map((msg, idx) => ( <div key={idx}><strong>{msg.user}:</strong> {msg.message}</div> ))} </div> </div> ); } export default App;
三、常见错误排查要点
- CORS配置不匹配:前端开启
withCredentials: true时,服务器CORS必须设置AllowCredentials(),且不能用AllowAnyOrigin(),需指定具体前端Origin。 - 路由路径不一致:服务器
MapHub("/chat")与前端withUrl(".../chat")的路径必须完全一致(包括大小写)。 - 端口冲突:确保服务器(如5000)和前端(如3000)使用不同端口,避免端口占用。
- HTTP/HTTPS混合:服务器用HTTPS时,前端必须用HTTPS连接,否则浏览器会拦截WebSocket请求。
- 中间件顺序错误:
UseCors必须在MapHub之前执行,否则CORS规则不会应用到SignalR请求。
内容的提问来源于stack exchange,提问作者Menura Wijesekara
相关产品推荐
相关产品推荐

