關於.net core 中的signalR組件的使用


SignalR是為了提供更方便的web交互響應式到推送式的解決方案。有了它之后可以實現客戶端直接調用服務端的方法並且獲得返回值 (客戶端可以是各種平台,目前SignalR支持的語言版本有C#、java、javaScript、nodejs等),服務端也是可以調用客戶端的方法,通過這樣的方式實現了由原來的單通變成雙通的目的。

在SignalR中有個非常重要的概念就是Hub,這個Hub如果拿到以前的MVC架構中所對應的就是控制器,他們的區別就是我們需要自己去注冊這個Hub的路由,而控制器是可以基於約定的。

首先創建一個Hub

 public class NewsPushHub:Hub
    {

    }

  這是一個新聞推送的Hub,它必須要繼承至Hub這個基類,Hub這個基類還可以接收一個泛型的實現,這個泛型可以用來規范客戶端的方法

  public class NewsPushHub : Hub<IClientFuncs>
    {
        /// <summary>
        /// 可以被客戶端調用的方法
        /// </summary>
        /// <param name="msg"></param>
        /// <returns></returns>
        public async Task DepartmentNotice(string msg)
        {
            //這里發送只能是接口中約束的方法
            await Clients.All.SendMsg( msg);
        }
    }
    /// <summary>
    /// 定義客戶端所監聽的方法名稱
    /// </summary>
    public interface IClientFuncs
    {
        Task SendMsg(string msg);
    }

  

這里面寫的兩個方法是可以被客戶端直接調用的,但是在被調用之前首先要注冊,在Core3.0之前 我們是用app.UseSignalR(hub=>hub.MapHub<NewsPushHub>("/SignalRNews"))來注冊SignalR的訪問路由,現在改成全部統一在app.UseEndpoints()這個擴展方法中去注冊,現在在Startup類的代碼就像這樣了
 
    public class Startup
    {
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddControllersWithViews();
            services.AddSignalR();
        }
        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }

            app.UseRouting();
            app.UseEndpoints(endpoints =>
            {
                endpoints.MapHub<NewsPushHub>("/SignalRNews");
                endpoints.MapControllerRoute("default", "{controller=Home}/{action=Index}/{id?}");
            }); 
          
        }

  在這個里面我配置了包含MVC的中間件和依賴注入,在3.0中MVC的中間件和依賴注入都變了  變得更加具體,路由設置也變得統一在UseEndpoints()這個方法里面,它里面的委托是一個IEndpointRouteBuilder的參數,我們通過這個參數可以映射各種路由配置,有非常多的map,在這里配置MVC的目的是為了和SignalR交互的。下面是客戶端的js代碼首先需要安裝aspnet-signalr

//創建一個匹配 http:localhost:5000/SignalRNews路由的連接
const connection = new signalR.HubConnectionBuilder()
    .withUrl("/SignalRNews")
    .configureLogging(signalR.LogLevel.Information)
    .build();
// 開始連接,這個時候會發送一個101狀態為pending的連接
connection.start().then(function () {
    console.log("connected");
});
// 監聽服務端調用的客戶端方法
connection.on("sendMsg", (msg) => {
    $(".dispaly-message").append(`<p>${msg}</p>`);
});

$("#submit").click(e => {
    const msg = $("#msg").val();
    // 調用服務端的DepartmentNotice方法
    connection.invoke("DepartmentNotice", msg).then(() => {
        console.log("消息發送完成");
    });
})

  

 

 

 

 上面是最終的結果 可以看出實現了不同客戶端之間的消息互通  

其實Signalr還可以有依賴注入的用法例如在控制器里面注入 然后直接在MVC中隨意推送消息

 

  public class HomeController:Controller
    {
        private readonly IHubContext<NewsPushHub> _hub;

        public HomeController(IHubContext<NewsPushHub> hub)
        {
            this._hub = hub;
        }
        public IActionResult Index()
        {
            _hub.Clients.All.SendAsync("Temp", "test");
            return View();
        }
       
       
    }

  從上面代碼中看的出在Home控制器中注入了NewsPushHub這個Hub 只要有一個客戶端訪問Index界面就會通知所有的客戶端

總結:SignalR把原來復雜低效率的雙通編程變得簡單,Siganlr只要是支持3中模式進行客戶端和服務端的連接(1、長輪詢模式  2、服務器發送事件  3、websocket)最高效的當然是websocket 但是某一些瀏覽器是不支持的;

以上代碼的demo地址


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM