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

如何在C#后端+React前端项目中搭建SignalR服务器?

SignalR 广播服务实现(React + C# 后端)

一、C# 后端配置

1. 安装依赖

在ASP.NET Core项目中,通过NuGet安装SignalR包:

dotnet add package Microsoft.AspNetCore.SignalR

2. 创建SignalR Hub

新建一个继承自Hub的类,用来处理消息接收与广播:

using Microsoft.AspNetCore.SignalR;

namespace YourProject.Hubs;

public class ChatHub : Hub
{
    // 接收前端消息并广播给所有在线客户端
    public async Task SendMessage(string username, string content)
    {
        // 触发客户端的ReceiveMessage事件
        await Clients.All.SendAsync("ReceiveMessage", username, content);
    }
}

3. 注册服务与配置中间件

在Program.cs中添加SignalR服务、配置CORS(解决跨域)并映射Hub端点:

var builder = WebApplication.CreateBuilder(args);

// 注册SignalR服务
builder.Services.AddSignalR();

// 配置CORS,允许React前端跨域请求
builder.Services.AddCors(options =>
{
    options.AddPolicy("ReactCorsPolicy", policy =>
    {
        policy.WithOrigins("http://localhost:3000") // 替换为你的React应用地址
              .AllowAnyHeader()
              .AllowAnyMethod()
              .AllowCredentials();
    });
});

var app = builder.Build();

// 启用CORS
app.UseCors("ReactCorsPolicy");

// 映射SignalR Hub的访问端点
app.MapHub<ChatHub>("/chatHub");

app.Run();

启动后端项目时,SignalR服务会随应用一同启动。

二、React 前端实现

1. 安装客户端依赖

在React项目根目录执行:

npm install @microsoft/signalr

2. 编写聊天组件

创建一个组件,负责SignalR连接、消息发送与接收展示:

import { useEffect, useState } from 'react';
import * as signalR from '@microsoft/signalr';

const SignalRChat = () => {
    const [hubConnection, setHubConnection] = useState(null);
    const [username, setUsername] = useState('');
    const [messageContent, setMessageContent] = useState('');
    const [messageList, setMessageList] = useState([]);

    // 初始化SignalR连接实例
    useEffect(() => {
        const connection = new signalR.HubConnectionBuilder()
            .withUrl('http://localhost:5000/chatHub') // 替换为后端Hub的地址
            .withAutomaticReconnect() // 配置自动重连
            .build();

        setHubConnection(connection);
    }, []);

    // 启动连接并监听消息
    useEffect(() => {
        if (!hubConnection) return;

        hubConnection.start()
            .then(() => console.log('SignalR连接成功'))
            .catch(err => console.error('连接失败:', err));

        // 监听后端推送的ReceiveMessage事件
        hubConnection.on('ReceiveMessage', (user, message) => {
            setMessageList(prev => [...prev, { user, message }]);
        });

        // 组件卸载时关闭连接
        return () => {
            hubConnection.stop();
        };
    }, [hubConnection]);

    // 发送消息到后端
    const handleSendMessage = async (e) => {
        e.preventDefault();
        if (!hubConnection || !username || !messageContent) return;

        try {
            await hubConnection.invoke('SendMessage', username, messageContent);
            setMessageContent(''); // 清空输入框
        } catch (err) {
            console.error('发送消息失败:', err);
        }
    };

    return (
        <div style={{ maxWidth: '600px', margin: '2rem auto' }}>
            <h2>SignalR 实时聊天</h2>
            <input
                type="text"
                placeholder="输入你的用户名"
                value={username}
                onChange={e => setUsername(e.target.value)}
                style={{ marginBottom: '1rem', padding: '0.5rem', width: '100%' }}
            />
            <form onSubmit={handleSendMessage} style={{ display: 'flex', gap: '0.5rem', marginBottom: '1rem' }}>
                <input
                    type="text"
                    placeholder="输入消息内容"
                    value={messageContent}
                    onChange={e => setMessageContent(e.target.value)}
                    disabled={!hubConnection}
                    style={{ flex: 1, padding: '0.5rem' }}
                />
                <button
                    type="submit"
                    disabled={!hubConnection || !username || !messageContent}
                    style={{ padding: '0.5rem 1rem' }}
                >
                    发送
                </button>
            </form>
            <div style={{ border: '1px solid #eee', padding: '1rem', maxHeight: '400px', overflowY: 'auto' }}>
                <h3>消息记录</h3>
                {messageList.map((msg, index) => (
                    <div key={index} style={{ marginBottom: '0.5rem' }}>
                        <strong>{msg.user}:</strong> {msg.message}
                    </div>
                ))}
            </div>
        </div>
    );
};

export default SignalRChat;

3. 在应用中使用组件

在App.js中引入并使用该组件:

import SignalRChat from './SignalRChat';

function App() {
    return (
        <div className="App">
            <SignalRChat />
        </div>
    );
}

export default App;

三、测试验证

  1. 启动C#后端项目
  2. 启动React前端项目(npm start)
  3. 打开多个浏览器窗口访问React应用,输入用户名和消息,所有窗口都会实时收到广播消息

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.02 10:51:39