ASP.NET Core SignalR 是微软开发的一套基于ASP.NET Core的与Web进行实时交互的类库,它使咱们的应用可以实时的把数据推送给Web客户端。javascript
自动管理链接java
容许同时广播到全部客户端git
也能够广播到指定的组或者特定的客户端github
在Github上开源,传送门(https://github.com/aspnet/signalr)服务器
SignalR 提供了多种链接方式,在现代化应用中,WebSocket是最佳的传输协议,在客户端没法实现WebSocket协议的时候,SignalR就会采起其余方式,好比Server-Sent或者长轮询(在ws未出现以前,咱们讨论的推拉模式)cookie
SignalR是采用中心客户端和服务器进行通信。app
中心是一种高级的管道,容许客户端和服务器之间相互调用方法。异步
中心经过强类型参数传递给方法,进行模型绑定async
Clients属性包含了全部的客户端链接信息,它包含了3个属性:ide
All 全部客户端
Caller 进行这次请求的客户端
Others 排除这次请求客户端的其余客户端
包含了多个方法:
= AllExcept 在指定的链接除外的全部链接的客户端上调用方法
Client 在特定链接的客户端上调用方法
Clients 在特定链接的客户端上调用方法
Group 调用指定的组中的一种对全部链接方法
GroupExcept 调用中指定的组,除非指定链接到的全部链接的方法
Groups 调用一种对多个组的链接方法
OthersInGroup 调用一种对一组的链接,不包括客户端调用 hub 方法方法
User 调用一种对与特定用户关联的全部链接方法
Users 调用一种对与指定的用户相关联的全部链接方法
每一个属性和方法返回的对象都包含一个SendAsync方法,能够对客户端进行调用。
能够在应用其余地方经过使用IHubContext,达到调用Hub的目的。
文本协议:JSON
二进制协议:MessagePack(https://msgpack.org/)
MessagePack相似于JSON,但传输比JSON更快,数据大小比JSON更小
建立的Hub必须继承Microsoft.AspNetCore.SignalR.Hub,Hub类已经包含了管理链接、组和发送接收消息的属性及事件
在Hub中使用的方法应该尽可能使用异步的方式,由于SignalR在发送和接收消息的时候使用的是异步方法。
在Startup.ConfigureServices中经过services.AddSignalR对SignalR进行注册
在Startup.Configure中经过app.UseSignalR方法对Hub路由进行配置
微软官方示范(https://docs.microsoft.com/en-us/aspnet/core/tutorials/signalr?view=aspnetcore-2.1&tabs=visual-studio)中的ChatHub:
using Microsoft.AspNetCore.SignalR; using System.Threading.Tasks; namespace SignalRChat.Hubs { public class ChatHub : Hub { //服务端方法 public async Task SendMessage(string user, string message) { //ReceiveMessage 为客户端方法,让全部客户端调用这个方法 await Clients.All.SendAsync("ReceiveMessage", user, message); } } }
上述代码为当收到客户端发来的SendMessage请求后(发送聊天信息),咱们把消息发送到全部客户端,让他们调用自身的ReceiveMessage方法。
一般状况下,在用户进行链接后,Connection会保存用户的用户标识,以便对特定用户进行发送消息。
能够实现IUserIdProvider来自定义获取用户的方法,例如:
public class CustomUserIdProvider : IUserIdProvider { public virtual string GetUserId(HubConnectionContext connection) { return connection.User?.FindFirst(ClaimTypes.Email)?.Value; } }
在Startup.ConfigureServices中注册:
services.AddSingleton<IUserIdProvider, CustomUserIdProvider>();
Client的方法
T All { get; }
至关于持久链接中的 Broadcast。
T AllExcept(params string[] excludeConnectionIds);
给排除本人全部人发送消息。
T Client(string connectionId);
跟Send操做就是同样的了。
T Clients(IList<string> connectionIds);
和Send操做的重载方法同样,能够给一批指定的人发送。
T Group(string groupName, params string[] excludeConnectionIds);
给房间中的指定人发送消息: Clients.Group("room1", "asdfasdfads");
T Groups(IList<string> groupNames, params string[] excludeConnectionIds);
给房间列表中的指定人发送消息; 【自然的聊天室功能】
T User(string userId);
这个和Client是有区别的。 这个userId => this.Context.Request.User.Identity.Name 【form验证】
cookie中间件来作到singlar的身份验证。
userId 是你本身定义的一个标识。
T Users(IList<string> userIds);
<script src="~/lib/signalr/signalr.js"></script> <script type="text/javascript"> const connection = new signalR.HubConnectionBuilder() .withUrl("/myChatHub") .configureLogging(signalR.LogLevel.Information) .build(); connection.start().catch(err => console.error(err.toString())); //定义方法使用connection.on方法来接收返回数据 connection.on("SendMessage", (user, message) => { const encodedMsg = user + " 说:" + message; const li = document.createElement("li"); li.textContent = encodedMsg; document.getElementById("messagesList").appendChild(li); }); document.getElementById("sendBtn").addEventListener("click", function () { var user = document.getElementById('userName').value; var message = document.getElementById('message').value; //从客户端中调用在此调用以前在自定义Hub定义的SendMessage方法 connection.invoke("SendMessage", user, message).catch(err => console.error(err.toString())); document.getElementById('message').value = ""; }); </script>