.net中SignalR的使用
前言
前面学习了asp.net长连接和websocket
asp.net实现长连接 - chenxizhaolu - 博客园
webSocket在.net中的使用案例 - chenxizhaolu - 博客园
今天学习下SignalR,这样实时Web功能三部曲就算学习完成了。
ASP.NET Core SignalR 是一个开放源代码库,用于简化向应用程序添加实时 Web 功能。实时 Web 功能允许服务器端代码在数据可用时立即将内容推送到连接的客户端,而不是让客户端周期性地轮询服务器以获取新数据。SignalR 特别适用于需要高频率数据更新的场景,如聊天应用、实时仪表板、游戏和协作工具等。
一个简单的聊天对话框
客户端发送消息到服务端,服务端回复。
服务端代码:
public class ChatHub : Hub { public async Task SendMessage(string user, string message) { await Clients.All.SendAsync("ReceiveMessage", user, "服务端收到了客户端的消息:" + message); } public override async Task OnConnectedAsync() { await Clients.All.SendAsync("ReceiveMessage", "System", $"{Context.ConnectionId} joined the chat"); await base.OnConnectedAsync(); } public override async Task OnDisconnectedAsync(Exception exception) { await Clients.All.SendAsync("ReceiveMessage", "System", $"{Context.ConnectionId} left the chat"); await base.OnDisconnectedAsync(exception); } }
var builder = WebApplication.CreateBuilder(args); builder.Services.AddCors(options => { options.AddPolicy("AllowAll", policy => { policy.WithOrigins("http://localhost:5065") // 允许所有来源 .AllowAnyMethod() // 允许所有 HTTP 方法 .AllowAnyHeader()// 允许所有请求头 .AllowCredentials(); }); }); builder.Services.AddSignalR(); builder.WebHost.UseUrls("http://localhost:5000"); var app = builder.Build(); // 启用 CORS 中间件 app.UseCors("AllowAll"); app.UseRouting(); app.MapHub<ChatHub>("/chatHub"); app.Run();
客户端代码:
var builder = WebApplication.CreateBuilder(args); var app = builder.Build(); app.UseStaticFiles(); app.Run();
<!-- wwwroot/index.html --> <!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <title>SignalR 聊天</title> <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet"> <style> body { padding-top: 50px; } #messages { height: 400px; overflow-y: scroll; border: 1px solid #ccc; padding: 10px; margin-bottom: 10px; } </style> </head> <body> <div class="container"> <h1 class="mt-5">SignalR 聊天</h1> <div id="messages"></div> <input type="text" id="userInput" class="form-control mt-2" placeholder="你的名字"> <input type="text" id="messageInput" class="form-control mt-2" placeholder="输入消息..."> <button id="sendButton" class="btn btn-primary mt-2">发送</button> </div> <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/microsoft-signalr/6.0.1/signalr.min.js"></script> <script> const connection = new signalR.HubConnectionBuilder() .withUrl("http://localhost:5000/chatHub", { withCredentials: true }) // 允许发送凭证 .configureLogging(signalR.LogLevel.Information) .build(); // 启动连接 connection.start().then(() => { console.log("SignalR 连接已建立"); }).catch(err => console.error(err.toString())); // 接收消息 connection.on("ReceiveMessage", (user, message) => { const msg = document.createElement("div"); msg.textContent = `${user}: ${message}`; document.getElementById("messages").appendChild(msg); window.scrollTo(0, document.body.scrollHeight); }); // 发送消息 document.getElementById("sendButton").addEventListener("click", async () => { const user = document.getElementById("userInput").value; const message = document.getElementById("messageInput").value; await connection.invoke("SendMessage", user, message); document.getElementById("messageInput").value = ""; }); </script> </body> </html>
实时推送功能
public class Worker : BackgroundService { private readonly ILogger<Worker> _logger; private readonly IHubContext<ChatHub> _chatHubContext; public Worker(ILogger<Worker> logger, IHubContext<ChatHub> chatHubContext) { _logger = logger; _chatHubContext = chatHubContext; } protected override async Task ExecuteAsync(CancellationToken stoppingToken) { while (!stoppingToken.IsCancellationRequested) { _logger.LogInformation("Worker running at: {time}", DateTimeOffset.Now); await _chatHubContext.Clients.All.SendAsync("OnlineUsers", "System", $"当前在线Connection: {string.Join(',', ChatHub.ConnectedConnections.Keys)}"); await Task.Delay(10000, stoppingToken); } } }
builder.Services.AddHostedService<Worker>();
简单看一下效果
客户端可以给服务端发送消息,服务端立马返回。如果想指定客户端返回,只需要修改SendAsync第一个参数,也就是methodName就可以。
服务端定时推送给所有客户端当前在线情况
SignalR Console客户端示例
源码地址:https://gitee.com/xiaoqingyao/keep-alive-http-demo.git
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!
2018-02-28 2018年新年计划