SignalR:React + ASP.NET Core Api
一、 后台WebApi配置:#
注:Vision为业务名称,以此为例,可随意修改
1. 安装包:Microsoft.AspNetCore.SignalR#
2. 注入#
Startup.cs ConfigureServices 添加以下代码:
services.AddSignalR();
Startup.cs Configure app.UseEndpoints 添加以下代码:
endpoints.MapHub<VisionHub>("/api/visionHub");
3. 创建通信中心类,继承Hub#
using Microsoft.AspNetCore.SignalR;
public class VisionHub : Hub
{
//重写连接事件,初次建立连接时进入此方法,开展具体业务可使用,例如管理连接池。
public override async Task OnConnectedAsync()
{
await Clients.Caller.SendAsync("connected", Context.ConnectionId);
}
//重写断开事件,同理。
public override async Task OnDisconnectedAsync(Exception exception)
{
await base.OnDisconnectedAsync(exception);
}
//服务端接收客户端发送方法
public async Task SendMessage(string message)
{
//第一个参数为客户端接收服务端返回方法,名称需要服务端一致。
await Clients.Caller.SendAsync("ReceiveMessage", Context.ConnectionId + ": " + message);
}
public async Task SendAllMessage(string message)
{
//第一个参数为客户端接收服务端返回方法,名称需要服务端一致。
await Clients.All.SendAsync("ReceiveMessage", Context.ConnectionId + ": " + message);
}
}
//Clients.All是全员广播,Clients.Caller是当前连接对象,也可以指定连接推送Clients.Client(id),id为在全局对象中获取:Context.ConnectionId
二、前台React配置#
1. 安装包:npm install @microsoft/signalr#
2. 连接配置#
import React, { useState, useEffect, useRef } from 'react';
import * as signalR from '@microsoft/signalr';
const Vision = () => {
const connectionRef = useRef(null);
useEffect(() => {
let cc;
const protocol = new signalR.JsonHubProtocol();
const transport = signalR.HttpTransportType.WebSockets;
const options = {
transport,
skipNegotiation: true,
};
cc = new signalR.HubConnectionBuilder()
.withUrl("http://localhost:8090/api/visionHub", options) //url需与后台注入一致。
.withHubProtocol(protocol)
.withAutomaticReconnect()
.build();
cc.serverTimeoutInMilliseconds = 60 * 1000 * 60 * 24;
cc.on('connected', onConnected)
cc.on('ReceiveMessage', onReceiveMessage)
cc.onreconnected(() => {
if (cc.connectionState != "Connected") {
onRegister();
}
});
cc.start().then(() => {
connectionRef.current = cc;
}).catch(err => {
console.error('SignalR Connection Error: ', err);
});
return () => {
if (cc) {
cc.stop();
}
}
}, [])
const onConnected = (connectionId) => {
document.getElementById("user").innerHTML = document.getElementById("user").innerHTML + connectionId;
}
const onReceiveMessage = (message) => {
document.getElementById("receiveMsg").innerHTML = document.getElementById("receiveMsg").innerHTML + message + "<br>";
}
const SendMessage = (method) => {
connectionRef.current.invoke(method, document.getElementById("sendMsg").value).catch((err) => {
console.error('Send', err);
});
}
return (
<div style={{ margin: 10 }}>
<div id="user" style={{ margin: 10 }}>张三(ConnectionId):</div>
<input id="sendMsg" style={{ margin: 10 }} />
<button type="button" onClick={() => SendMessage("SendMessage")} style={{ margin: 10 }}>Send</button>
<button type="button" onClick={() => SendMessage("SendAllMessage")} style={{ margin: 10 }}>广播</button>
<div style={{ margin: 10 }}>服务器:</div>
<div id="receiveMsg" style={{ margin: 10 }}></div>
</div>
)
}
export default Vision
三、效果图#
模拟张三上线,生成ConnectionId,单独与广播两种方式与服务器通信
更多强大功能请阅读官方文档:SignalR
作者:冬先生
出处:https://www.cnblogs.com/WinterSir/p/14595654.html
版权:本作品采用「署名-非商业性使用-相同方式共享 4.0 国际」许可协议进行许可。
内容粗浅,如有错误,欢迎大佬批评指正
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 一个奇形怪状的面试题:Bean中的CHM要不要加volatile?
· [.NET]调用本地 Deepseek 模型
· 一个费力不讨好的项目,让我损失了近一半的绩效!
· .NET Core 托管堆内存泄露/CPU异常的常见思路
· PostgreSQL 和 SQL Server 在统计信息维护中的关键差异
· DeepSeek “源神”启动!「GitHub 热点速览」
· 微软正式发布.NET 10 Preview 1:开启下一代开发框架新篇章
· C# 集成 DeepSeek 模型实现 AI 私有化(本地部署与 API 调用教程)
· DeepSeek R1 简明指南:架构、训练、本地部署及硬件要求
· 2 本地部署DeepSeek模型构建本地知识库+联网搜索详细步骤