如何在ReactJS应用中集成SignalR实现C#后端长任务消息推送?
SignalR能否实现实时状态推送?完全可以!
SignalR是微软专为.NET生态打造的实时双向通信库,完美适配你这种后端长时间运行进程向前端推送状态更新的场景。下面是快速集成到C#后端和React前端的步骤:
一、C#后端集成(以ASP.NET Core Web API为例)
1. 安装SignalR NuGet包
在后端项目中执行以下命令安装依赖:
dotnet add package Microsoft.AspNetCore.SignalR
2. 创建SignalR Hub类
新建一个继承自Hub的类,作为前端与后端通信的核心枢纽:
using Microsoft.AspNetCore.SignalR; public class ProgressHub : Hub { // 这里可以定义供前端主动调用的方法,若仅后端推送则留空即可 }
3. 配置SignalR中间件
在Program.cs中注册SignalR服务并映射Hub端点:
var builder = WebApplication.CreateBuilder(args); // 注册SignalR服务 builder.Services.AddSignalR(); // 配置CORS(解决前后端跨域问题,替换为你的前端地址) builder.Services.AddCors(options => { options.AddPolicy("AllowReact", policy => policy.WithOrigins("http://localhost:3000") .AllowAnyHeader() .AllowAnyMethod() .AllowCredentials()); }); var app = builder.Build(); app.UseCors("AllowReact"); app.UseRouting(); // 映射Hub的访问端点 app.MapHub<ProgressHub>("/progressHub"); app.Run();
4. 在长时间进程中推送状态
注入IHubContext<ProgressHub>来获取Hub上下文,实现向指定客户端推送消息:
using Microsoft.AspNetCore.SignalR; public class LongRunningProcessService { private readonly IHubContext<ProgressHub> _hubContext; public LongRunningProcessService(IHubContext<ProgressHub> hubContext) { _hubContext = hubContext; } public async Task ExecuteAsync(string connectionId) { // 模拟长时间运行的任务 for (int i = 0; i <= 100; i += 10) { await Task.Delay(1000); // 向指定连接推送进度更新 await _hubContext.Clients.Client(connectionId) .SendAsync("ReceiveProgress", new { Progress = i, Status = $"当前完成{i}%" }); } // 推送完成消息 await _hubContext.Clients.Client(connectionId) .SendAsync("ReceiveProgress", new { Progress = 100, Status = "任务已完成" }); } }
5. 接口触发长时间进程
添加API接口供前端启动任务:
[ApiController] [Route("api/process")] public class ProcessController : ControllerBase { private readonly LongRunningProcessService _processService; public ProcessController(LongRunningProcessService processService) { _processService = processService; } [HttpPost("start")] public IActionResult Start([FromQuery] string connectionId) { // 后台异步执行,避免阻塞API请求 _ = _processService.ExecuteAsync(connectionId); return Ok("任务已启动"); } }
二、React前端集成
1. 安装SignalR客户端包
在React项目中执行:
npm install @microsoft/signalr
2. 创建状态监控组件
编写组件建立SignalR连接、监听后端推送的进度:
import { useEffect, useState } from 'react'; import { HubConnectionBuilder } from '@microsoft/signalr'; const ProgressMonitor = () => { const [progress, setProgress] = useState(0); const [status, setStatus] = useState(''); const [connection, setConnection] = useState(null); const [connectionId, setConnectionId] = useState(''); useEffect(() => { // 构建SignalR连接 const initConnection = async () => { const newConn = new HubConnectionBuilder() .withUrl('http://localhost:5000/progressHub') // 替换为你的后端Hub地址 .withAutomaticReconnect() // 自动重连 .build(); // 监听进度更新 newConn.on('ReceiveProgress', (update) => { setProgress(update.Progress); setStatus(update.Status); }); // 启动连接 try { await newConn.start(); setConnection(newConn); setConnectionId(newConn.connectionId); console.log('SignalR连接成功'); } catch (err) { console.error('连接失败:', err); } }; initConnection(); // 组件卸载时关闭连接 return () => { connection?.stop(); }; }, []); // 触发后端长时间进程 const startProcess = async () => { if (!connectionId) return; await fetch(`http://localhost:5000/api/process/start?connectionId=${connectionId}`, { method: 'POST' }); }; return ( <div className="progress-monitor"> <h3>任务进度监控</h3> <button onClick={startProcess} disabled={progress === 100} > 启动任务 </button> <div className="progress-bar"> <div className="progress-fill" style={{ width: `${progress}%` }} ></div> </div> <p>{status}</p> <p>当前进度: {progress}%</p> </div> ); }; export default ProgressMonitor;
关键注意事项
- 连接标识:示例中用
connectionId定位客户端,若需针对特定用户推送,可结合ASP.NET Core身份认证,通过Context.UserIdentifier获取用户ID,使用Clients.User(userId)推送。 - 重连处理:
withAutomaticReconnect()会自动处理连接断开后的重连,也可监听reconnecting/reconnected事件自定义逻辑。 - 异步执行:长时间进程必须异步执行,避免阻塞API请求线程。
内容的提问来源于stack exchange,提问作者Crystal
相关产品推荐
相关产品推荐

