[SignalR] - 由 WebAPI 服务向 Web 页面主动实时推送消息
框架
后端服务:.Net Core 3.1 WebAPI
前端页面:.Net Core 3.1 MVC
服务端
1. 跨域配置(CORS)
使用 Nuget 安装 Microsoft.AspNet.WebApi.Cors
2. 项目配置(Startup)
public class Startup { public Startup(IConfiguration configuration) { Configuration = configuration; } public IConfiguration Configuration { get; } // This method gets called by the runtime. Use this method to add services to the container. public void ConfigureServices(IServiceCollection services) { services.AddControllers(); services.AddSignalR(); services.AddCors(op => { op.AddPolicy("cors", set => { set.SetIsOriginAllowed(origin => true).AllowAnyHeader().AllowAnyMethod().AllowCredentials(); }); }); } // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } app.UseCors("cors"); app.UseRouting(); app.UseAuthorization(); app.UseEndpoints(endpoints => { endpoints.MapControllers(); endpoints.MapHub<NotificationHub>("/NotificationHub"); }); } }
3. 业务逻辑,主动推送消息
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | [ApiController] [Route( "[controller]" )] public class NotificationController : ControllerBase { private readonly ILogger<NotificationController> _logger; private readonly IHubContext<NotificationHub> _hubContext; public NotificationController(ILogger<NotificationController> logger, IHubContext<NotificationHub> hubContext) { _logger = logger; _hubContext = hubContext; } [HttpGet] public string Get() { var message = new NotificationModel { Gid = Guid.NewGuid() }; var json = Newtonsoft.Json.JsonConvert.SerializeObject(message); //_hubContext.Clients.All.SendAsync("NotificationCenter", json); _hubContext.Clients.Group( "5f3b332bbdae582770fb5ec9" ).SendAsync( "NotificationCenter" , json); return Convert.ToString(json); } } public class NotificationModel { public Guid Gid { get ; set ; } } |
客户端配置
1. 为解决方案添加 SignalR 客户端库
2. 业务逻辑,接收推送过来的消息
"use strict"; var connection = new signalR.HubConnectionBuilder().withUrl("http://localhost:7370/NotificationHub").build(); connection.start().then(function () { var groupId = "5f3b332bbdae582770fb5ec9"; connection.invoke("AddToGroup", groupId); }).catch(function (err) { return console.error(err.toString()); }); connection.on("NotificationCenter", function (json) { var _obj = JSON.parse(json); var _div = document.createElement('div'); _div.innerText = _obj.Gid; document.getElementById("messagesList").appendChild(_div); });
范例演示
指定推送对象
所有连接的客户。 Clients.All.addContosoChatMessageToPage(name, message); 只有呼叫客户端。 Clients.Caller.addContosoChatMessageToPage(name, message); 除呼叫客户端外的所有客户端。 Clients.Others.addContosoChatMessageToPage(name, message); 由连接ID标识的特定客户端。 Clients.Client(Context.ConnectionId).addContosoChatMessageToPage(name, message); 除了指定的客户端的所有连接的客户端,由连接ID标识。 Clients.AllExcept(connectionId1, connectionId2).addContosoChatMessageToPage(name, message); 在指定的组中的所有连接的客户端。 Clients.Group(groupName).addContosoChatMessageToPage(name, message); 指定组中除指定客户端外的所有已连接客户端,由连接ID标识。 Clients.Group(groupName, connectionId1, connectionId2).addContosoChatMessageToPage(name, message); 指定组中除呼叫客户端外的所有已连接客户端。 Clients.OthersInGroup(groupName).addContosoChatMessageToPage(name, message); 由userId标识的特定用户。 Clients.User(userid).addContosoChatMessageToPage(name, message); (默认情况下,这是IPrincipal.Identity.Name可以通过向全局主机注册IUserIdProvider的实现来更改的。) 连接ID列表中的所有客户端和组。 Clients.Clients(ConnectionIds).broadcastMessage(name, message); 组ID列表中的所有组。 Clients.Groups(GroupIds).broadcastMessage(name, message); 用户名标识的客户端。 Clients.Client(username).broadcastMessage(name, message); 用户名列表对应的所有客户端(在SignalR 2.1中引入)。 Clients.Users(new string[] { "myUser", "myUser2" }).broadcastMessage(name, message);
参考资料
Tutorial: Get started with ASP.NET Core SignalR
https://docs.microsoft.com/en-us/aspnet/core/tutorials/signalr?view=aspnetcore-3.1&tabs=visual-studio
Manage users and groups in SignalR
https://docs.microsoft.com/en-us/aspnet/core/signalr/groups?view=aspnetcore-3.1#groups-in-signalr
ASP.NET SignalR 系列教程
https://www.cnblogs.com/fei686868/tag/SignalR/
ASP.NET Core SignalR CORS 跨域问题
https://www.cnblogs.com/IT-Ramon/p/12156832.html
signalR服务端调用客户端方法说明
https://blog.csdn.net/niuc321/article/details/80348108
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库