業務情景一:上傳報表,上傳excel。若是excel的數據量很大,上萬條,上十萬條數據,那麼這個上傳請求必然是個耗時請求。用戶上傳以後,很關心上傳的進度和結果。html
業務情景二:站內消息提醒,實時有效地接受消息。前端
對於這些需求,第一時間想到的是,前端定時去輪詢數據,返回一個進度或者未讀的站內消息。jquery
這樣雖然能達到目的,可是付出的代價是昂貴的。站點24小時,不斷地在請求接口,數據庫不斷地在被訪問,這是客戶端主動請求所帶來的弊端。數據庫
換一個角度,若是是服務端主動去推送消息給客戶端,那麼性能勢必能大幅增長,同時推送的消息更爲及時、準確。服務器
SignalR對經常使用實時通信技術進行了封裝, SignalR當WebSocket可用時優先使用新式的WebSocket傳輸,同時也兼容老式的傳輸。app
SignalR支持以一種簡單的API來建立服務器到客戶端的遠程調用客戶端的Javascript方法,SignalR還包括用於用於鏈接管理的API和分組鏈接。async
新建一個.net core console程序,引入nuget包ide
如下是服務端代碼,主程序建立了一個站內,站點啓動時注入了一個hubcontext的實例,這個hubcontext的主要工做是,每隔一秒鐘觸發客戶端去執行OnReportPublished方法。性能
1 using Microsoft.AspNetCore; 2 using Microsoft.AspNetCore.Builder; 3 using Microsoft.AspNetCore.Hosting; 4 using Microsoft.AspNetCore.SignalR; 5 using Microsoft.Extensions.DependencyInjection; 6 using System; 7 using System.Threading; 8 using System.Threading.Tasks; 9 10 namespace OneCode.SignalR 11 { 12 public class Program 13 { 14 public static void Main(string[] args) 15 { 16 BuildWebHost(args).Run(); 17 } 18 19 public static IWebHost BuildWebHost(string[] args) => 20 WebHost.CreateDefaultBuilder(args) 21 .UseStartup<Startup>() 22 .Build(); 23 } 24 25 public class MyHub : Hub 26 { 27 //此方法用於被客戶端調用,當客戶端執行 hubConnection.invoke('PublishReport', $('#reportName').val()); 會觸發此方法執行 28 public Task PublishReport(string reportName) 29 { 30 //主動通知客戶端去執行客戶端自己的方法,此代碼執行後 31 //hubConnection.on('OnReportPublished', data => { 32 // $('#reports').append($('<li>').text(data)); 33 //}); 34 35 //客戶端將執行 OnReportPublished 36 return Clients.All.InvokeAsync("OnReportPublished", reportName); 37 } 38 39 public async void Echo(string sendMan) 40 { 41 while (true) 42 { 43 await Clients.All.InvokeAsync("OnReportPublished", $"{DateTime.Now}:{sendMan}:{ Guid.NewGuid().ToString()}"); 44 Thread.Sleep(1 * 1000); 45 } 46 } 47 } 48 49 public class Startup 50 { 51 public void ConfigureServices(IServiceCollection services) 52 { 53 services.AddCors(options => 54 { 55 options.AddPolicy("fiver", 56 policy => policy.AllowAnyOrigin() 57 .AllowAnyHeader() 58 .AllowAnyMethod()); 59 }); 60 61 services.AddSignalR(); // <-- SignalR 62 63 } 64 65 public void Configure(IApplicationBuilder app, IHostingEnvironment env) 66 { 67 app.UseDeveloperExceptionPage(); 68 app.UseCors("fiver"); 69 70 app.UseSignalR(routes => // <-- SignalR 71 { 72 routes.MapHub<MyHub>("myHub"); 73 }); 74 75 //IHubContext<MyHub> hubContext = serviceProvider.GetService<IHubContext<MyHub>>(); 76 } 77 } 78 }
如下是客戶端代碼ui
<!DOCTYPE html> <html> <head> <meta name="viewport" content="width=device-width" /> <title>ASP.NET Core SignalR</title> <script src="js/signalr-client.min.js"></script> <script src="js/jquery.min.js"></script> </head> <body> <div> <h2>Reports</h2> <button id="button">send</button> <ul id="reports"></ul> <script> $(function () { let hubUrl = 'http://localhost:5000/myHub'; let httpConnection = new signalR.HttpConnection(hubUrl); let hubConnection = new signalR.HubConnection(httpConnection); $("#button").click(function () { hubConnection.invoke('Echo', 'wiky'); }); hubConnection.on('OnReportPublished', data => { $('#reports').append($('<li>').text(data)); }); hubConnection.start(); }); </script> </div> </body> </html>
如下是執行結果: