1. 程式人生 > 其它 >SignalR 入門 .netCore實現聊天室

SignalR 入門 .netCore實現聊天室

SignalR 入門 .netCore實現聊天室

本文根據微軟SignalR 簡介 | Microsoft DocsASP.NET Core SignalR 簡介 | Microsoft Docs 內容,結合自己學習過程中的理解而成,希望對大家認識和使用SinalR有幫助。

目錄

什麼是SignalR?

ASP.NET SignalR 是 ASP.NET 開發人員的庫

可以用來幹什麼?

可簡化將實時 web 功能新增到應用程式的過程。 實時 web 功能使伺服器程式碼能夠在可用時立即將內容推送到連線的客戶端,而不是讓伺服器等待客戶端請求新的資料。

SignalR 自動處理連線管理,讓你可同時向所有連線的客戶端廣播訊息,就像聊天室一樣。 也可以向特定客戶端傳送訊息。 客戶端和伺服器之間的連線是持久的,不同於傳統的 HTTP 連線,後者針對每次通訊重新建立。

SignalR 支援 "伺服器推送" 功能,在該功能中,伺服器程式碼可以使用遠端過程呼叫來呼叫瀏覽器中的客戶端程式碼

(RPC) [1],而不是目前在 web 上通用的請求-響應模式。

傳統的獲取伺服器資料的方法是:通過客戶端向伺服器傳送請求,伺服器相應請求返回資料給客戶端的方式(請求-響應模式)。而SinalR實現伺服器主動向客戶端推送資料。

SignalR怎麼實現伺服器和客戶端之間的通訊?

SignalR 使用 集線器Hub 在客戶端和伺服器之間進行通訊。

中心是一種高階管道,它允許客戶端和伺服器分別呼叫方法。 SignalR 自動處理跨計算機邊界的排程,使客戶端能夠在伺服器上呼叫方法,反之亦然。 可以將強型別引數傳遞給方法,從而啟用模型繫結。 SignalR 提供了兩個內建的集線器協議:基於 JSON 的文字協議和基於

MessagePack的二進位制協議。 與 JSON 相比,MessagePack 通常會建立較小的訊息。 較早的瀏覽器必須支援 XHR 級別 2 ,才能提供 MessagePack 協議支援。

中心通過傳送包含客戶端方法的名稱和引數的訊息來呼叫客戶端程式碼。 作為方法引數傳送的物件將使用配置的協議進行反序列化。 客戶端嘗試將名稱與客戶端程式碼中的方法匹配。 當客戶端找到匹配項時,它將呼叫方法並向其傳遞反序列化的引數資料。

程式碼實現:ASP.NET Core SignalR 入門 | Microsoft Docs

實現一個聊天室的場景demo,測試:開啟兩個瀏覽器聊天,顯示聊天列表

新增 SignalR 客戶端庫。
  • 在“解決方案資源管理器”中,右鍵單擊專案,然後選擇“新增”>“客戶端庫” 。
  • 在“新增客戶端庫”對話方塊中,對於“提供程式”,選擇“unpkg”。
  • 對於“庫”,輸入 @microsoft/signalr@latest
  • 選擇“選擇特定檔案”,展開“dist/browser”資料夾,然後選擇“signalr.js”和“signalr.min.js”。
  • 將“目標位置”設定為 wwwroot/js/signalr/,然後選擇“安裝”。
建立 SignalR 中心。

中心 是一個類,用作處理客戶端 - 伺服器通訊的高階管道。

  • 在 SignalRChat 專案資料夾中,建立 Hubs 資料夾。

  • 在 Hubs 資料夾中,使用以下程式碼建立 chatHub.cs 檔案 :

    using Microsoft.AspNetCore.SignalR;
    using System.Threading.Tasks;
    
    namespace SignalRChat.Hubs
    {
        public class ChatHub : Hub
        {
            public async Task SendMessage(string user, string message)
            {
                await Clients.All.SendAsync("ReceiveMessage", user, message);
            }
        }
    }
    
配置.netCore專案以使用 SignalR服務。
using SignalRChat.Hubs;

 public void ConfigureServices(IServiceCollection services)
        {
            ...
            services.AddSignalR();
        }

 public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
     		...
     		app.UseEndpoints(endpoints =>
            {
                ...
                endpoints.MapHub<ChatHub>("/chatHub");
            });
		 }

這些更改將 SignalR 新增到 ASP.NET Core 依賴關係注入和路由系統。

新增可將訊息從任何客戶端傳送到所有連線客戶端的程式碼。

html

<div class="container">
        <div class="row">&nbsp;</div>
        <div class="row">
            <div class="col-2">User</div>
            <div class="col-4"><input type="text" id="userInput" /></div>
        </div>
        <div class="row">
            <div class="col-2">Message</div>
            <div class="col-4"><input type="text" id="messageInput" /></div>
        </div>
        <div class="row">&nbsp;</div>
        <div class="row">
            <div class="col-6">
                <input type="button" id="sendButton" value="Send Message" />
            </div>
        </div>
    </div>
    <div class="row">
        <div class="col-12">
            <hr />
        </div>
    </div>
    <div class="row">
        <div class="col-6">
            <ul id="messagesList"></ul>
        </div>
    </div>
<script src="~/js/signalr/dist/browser/signalr.js"></script>
<script src="~/js/chat.js"></script>

javascript

"use strict";

var connection = new signalR.HubConnectionBuilder().withUrl("/chatHub").build();

//Disable send button until connection is established
document.getElementById("sendButton").disabled = true;

connection.on("ReceiveMessage", function (user, message) {
    var li = document.createElement("li");
    document.getElementById("messagesList").appendChild(li);
    // We can assign user-supplied strings to an element's textContent because it
    // is not interpreted as markup. If you're assigning in any other way, you 
    // should be aware of possible script injection concerns.
    li.textContent = `${user} says ${message}`;
});

connection.start().then(function () {
    document.getElementById("sendButton").disabled = false;
}).catch(function (err) {
    return console.error(err.toString());
});

document.getElementById("sendButton").addEventListener("click", function (event) {
    var user = document.getElementById("userInput").value;
    var message = document.getElementById("messageInput").value;
    connection.invoke("SendMessage", user, message).catch(function (err) {
        return console.error(err.toString());
    });
    event.preventDefault();
});

前面的程式碼:

  • 建立並啟動連線。
  • 向“提交”按鈕新增一個用於向中心傳送訊息的處理程式。
  • 向連線物件新增一個用於從中心接收訊息並將其新增到列表的處理程式。

  1. RPC(Remote Procedure Call)譯作:遠端過程呼叫,是一種通過網路從遠端計算機程式上請求服務而不需要了解底層網路技術的思想。 RPC 是一種技術思想而非一種規範或協議,常見的技術和框架有:應用級的服務框架:阿里的 Dubbo/Dubbox、Google gRPC、Spring Boot/Spring Cloud。遠端通訊協議:RMI、Socket、SOAP(HTTP XML)、REST(HTTP JSON)。通訊框架:MINA 和 Netty。花了一個星期,我終於把RPC框架整明白了! - 51CTO.COMRPC是什麼,看完你就知道了 - 知乎 (zhihu.com) ↩︎

本文來自部落格園,作者:jiayouliucui,轉載請註明原文連結:https://www.cnblogs.com/cheery-go/p/15711166.html