ASP.NET Core SignalR

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

中心 Hubs

SignalR是採用中心客戶端和服務器進行通信。app

中心是一種高級的管道,容許客戶端和服務器之間相互調用方法。異步

中心經過強類型參數傳遞給方法,進行模型綁定async

Hubs.Clients

Clients屬性包含了全部的客戶端鏈接信息,它包含了3個屬性:ide

  • All 全部客戶端

  • Caller 進行這次請求的客戶端

  • Others 排除這次請求客戶端的其餘客戶端

包含了多個方法:

  • = AllExcept 在指定的鏈接除外的全部鏈接的客戶端上調用方法

  • Client 在特定鏈接的客戶端上調用方法

  • Clients 在特定鏈接的客戶端上調用方法

  • Group 調用指定的組中的一種對全部鏈接方法

  • GroupExcept 調用中指定的組,除非指定鏈接到的全部鏈接的方法

  • Groups 調用一種對多個組的鏈接方法

  • OthersInGroup 調用一種對一組的鏈接,不包括客戶端調用 hub 方法方法

  • User 調用一種對與特定用戶關聯的全部鏈接方法

  • Users 調用一種對與指定的用戶相關聯的全部鏈接方法

每一個屬性和方法返回的對象都包含一個SendAsync方法,能夠對客戶端進行調用。

HubContext

能夠在應用其餘地方經過使用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);

 

客戶端JS使用方法

<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>
相關文章
相關標籤/搜索