signalR 消息推送

業務情景一:上傳報表,上傳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>

 

如下是執行結果:

 

相關文章
相關標籤/搜索