首頁>技術>

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 但是某一些瀏覽器是不支援的;

程式碼地址:https://github.com/hulijuanAndXiaoLv/signalrDemo

原文地址:https://www.cnblogs.com/lvshunbin/p/11622758.html

  • BSA-TRITC(10mg/ml) TRITC-BSA 牛血清白蛋白改性標記羅丹明
  • Node.js實現使用者評論社群(體驗前後端開發的樂趣)