第五節:SignalR大雜燴(與MVC融合、全局的幾個配置、跨域的應用、C/S程式充當Client和Server)

来源:https://www.cnblogs.com/yaopengfei/archive/2018/07/18/9327321.html
-Advertisement-
Play Games

一. 說在前面的話 本節主要在前面章節的基礎上補充了幾個簡單的知識點,比如:第三方調用通過 GlobalHost.ConnectionManager.GetHubContext<MySpecHub1>();來獲取Hub對象,那麼能不能封裝一下不必每次都這麼獲取呢?再比如SignalR傳輸是否有大小限 ...


一. 說在前面的話

  本節主要在前面章節的基礎上補充了幾個簡單的知識點,比如:第三方調用通過 GlobalHost.ConnectionManager.GetHubContext<MySpecHub1>();來獲取Hub對象,那麼能不能封裝一下不必每次都這麼獲取呢?再比如SignalR傳輸是否有大小限制,一下傳輸10w個字能否傳輸成功?最後著重整理一下跨域的各種使用情況,結合C/S程式充當客戶端和伺服器端。

  本節內容包括:

    ①. SignalR與MVC或者WebApi簡單的整合。

    ②. 全局的幾個配置。

    ③. 跨域的配置和應用。

    ④. C/S程式充當客戶端或伺服器端。

 

二. SignalR與MVC的簡單整合

   在前面的章節中我們已經知道,如果要通過控制器中的Action來實現通訊,需要通過 GlobalHost.ConnectionManager.GetHubContext<MySpecHub1>(); 來獲取Hub類,但是每個Action中都這麼獲取,顯得有點麻煩,這裡簡單封裝一下,來便捷開發。

    分析:實質在我們在Action中用到的對象無非也就這兩個,IHubConnectionContext<dynamic> Clients  和  IGroupManager Groups ,所以這裡利用繼承的關係簡單的封裝一下,聲明BaseController類,在裡面獲取這兩個對象,然後其它控制器繼承BaseController,並傳入對應的Hub類,這樣在Action中就可以直接使用 Clients和Groups了。

  PS:WepAPI程式可以採用下麵類似方式進行封裝。

  BaseController代碼展示:

 1     /// <summary>
 2     /// 整合MVC和SignalR
 3     /// </summary>
 4     public class BaseController<T> : Controller where T : Hub
 5     {
 6         public IHubConnectionContext<dynamic> Clients { get; set; }
 7 
 8         public IGroupManager Groups { get; set; }
 9 
10         public BaseController()
11         {
12             var hub = GlobalHost.ConnectionManager.GetHubContext<T>();
13             Clients = hub.Clients;
14             Groups = hub.Groups;
15         }
16     }

  繼承BaseController的代碼展示:

 1  public class HubController : BaseController<MySpecHub1>
 2     {
 3        
 4         /// <summary>
 5         /// 向所有人發送消息
 6         /// </summary>
 7         /// <param name="myConnectionId">當前用戶的登錄標記</param>
 8         /// <param name="msg">發送的信息</param>
 9         public string MySendAll(string myConnectionId, string msg)
10         {
11             //Hub模式
12             Clients.AllExcept(myConnectionId).receiveMsg($"用戶【{myConnectionId}】發來消息:{msg}");
13             return "ok";
14         }
15 
16     }

   

三. 全局的幾個配置

   這裡的全局配置主要包括:傳輸超時時間、強制關閉時間、WebSocket模式下允許傳輸的數據最大值等等,以下配置代碼可以在Configuration方法中進行配置,可以根據實際業務情況自行選擇配置。

  1. 表示客戶端在轉而使用其他傳輸或連接失敗之前應允許連接的時間。預設值為 5 秒。(傳輸超時時間)

    GlobalHost.Configuration.TransportConnectTimeout = TimeSpan.FromSeconds(5);

  2. 表示連接在超時之前保持打開狀態的時間

    GlobalHost.Configuration.TransportConnectTimeout = TimeSpan.FromSeconds(5);

  3. 用於表示在連接停止之後引發斷開連接事件之前要等待的時間。 (強制關閉時間)

    GlobalHost.Configuration.DisconnectTimeout = TimeSpan.FromSeconds(5);

  4. 表示兩次發送保持活動消息之間的時間長度。如果啟用,此值必須至少為兩秒。設置為 null 可禁用。

    GlobalHost.Configuration.KeepAlive = TimeSpan.FromSeconds(2);

  5. Websocket模式下允許傳輸數據的最大值,預設為64kb

    GlobalHost.Configuration.MaxIncomingWebSocketMessageSize = 64;

 

四. 跨域的應用

   在很多情況下,前後端是分離,客戶端和伺服器端並不在一個地址下,比如APP(這裡指混合開發能使用JS的情況下),這個時候伺服器的SignalR就需要配置允許跨域,這裡有兩種允許跨域的策略,一種是JSONP模式,另外一種是Cors模式。

  在Startup類中的Configuration方法中進行配置,代碼如下

 1   public class Startup
 2     {
 3         public void Configuration(IAppBuilder app)
 4         {
 5           //配置允許跨域
 6             //1. JSONP模式
 7             //app.MapSignalR(new HubConfiguration() { EnableJSONP = true });
 8 
 9             //2. Cors模式(需要安裝Microsoft.Owin.Cors程式集)
10             app.UseCors(CorsOptions.AllowAll).MapSignalR();
11         }
12     }

  註:採用Cors模式的跨域需要安裝:Microsoft.Owin.Cors 程式集,並且上述代碼沒有單獨配置模型路徑,所以採用的是預設路徑“/signalr”。

  當然前端代碼也需要進行相應的改寫:

(1). 代理模式的改寫形式:

   a. 自動生成代理類代碼需要改寫為 <script src="http://localhost:7080/signalr/hubs"></script> ,localhost:7080,根據實際情況改為實際地址。

      b. 需要單獨配置一下Hub的連接路徑, conn.url = "http://localhost:7080/signalr";

 以上兩步即為全部改變,其餘位置不需變化。

(2). 非代理模式下的代碼:

   非代理模式下就更容易,只需要在hubConnection方法中傳入路徑即可。如下圖:

 

五. C/S程式充當客戶端

   C/S程式(這裡採用控制台)充當客戶端,當然伺服器端必須已經配置了允許跨域,且C/S程式是沒有JS的,所以只能採用非代理模式。

 步驟如下:

  1:安裝程式集 Microsoft.AspNet.SignalR.Client

  2:代碼配置

    a. 與伺服器路徑匹配的時候要註意,預設路徑的話,要加上signalr/

    b. 如果定義的方法大於一個參數的時候,需要聲明一個類來接收

    eg:Proxy.On<Person>("方法名", Person=>

      Console.WriteLine("ID{0} Name{1}", Person.ID, Person.Name));

 代碼如下:

 1   class Program
 2     {
 3         static void Main(string[] args)
 4         {
 5 
 6             //一. 基礎信息配置
 7             //1. 與伺服器路徑進行匹配
 8             var conn = new HubConnection("http://localhost:8099/signalr/");
 9             //2. 創建代理類
10             var proxy = conn.CreateHubProxy("MySpecHub1");
11 
12 
13             //二. 定義客戶端的方法
14             //特別註意,如果定義的方法大於一個參數的時候,msg的位置需要聲明一個類來接受
15             //1 接受用戶登錄成功後的提示
16 
17             proxy.On("LoginSuccessNotice", (msg) =>
18             {
19                 Console.WriteLine(msg);
20             });
21 
22             //2  接收自己的connectionId
23             proxy.On("ReceiveOwnCid", (msg) =>
24             {
25                 Console.WriteLine(msg);
26             });
27 
28             //三. 啟動
29             conn.Start().Wait();
30 
31             Console.ReadKey();
32 
33         }
34     }

 

六. C/S程式充當伺服器端

   在很多情況下,我們需要避免使用IIS的性能開銷,或者要將SignalR部署成Windows服務,這個使用就需要使用C/S程式作為伺服器端了。

 配置步驟比較簡單,如下: 

1. 安裝程式集:Microsoft.AspNet.SignalR.SelfHost 和 Microsoft.Owin.Cors(跨域使用)

2. 添加集線器類MySpecHub1

3. 在Startup中配置允許跨域

4. 編寫啟動代碼

 PS:以上步驟2和步驟3在前面章節中已經多次提到過了,這裡指展示一下啟動代碼:

 1       static void Main(string[] args)
 2         {
 3             try
 4             {
 5                 string url = "http://localhost:7080";
 6                 using (WebApp.Start<Startup>(url))
 7                 {
 8                     Console.WriteLine("Server running on {0}", url);
 9                     Console.ReadLine();
10                 }
11             }
12             catch (Exception ex)
13             {
14                 Console.WriteLine(ex.Message);
15             }
16             Console.ReadKey();
17         }

  特別註意:如果報System.Reflection.TargetInvocationException was unhandled,直接去bin文件里以管理員身份運行exe程式即可或者以管理員身份運行VS程式然後啟動即可。

 

 

 

!

  • 作       者 : Yaopengfei(姚鵬飛)
  • 博客地址 : http://www.cnblogs.com/yaopengfei/
  • 聲     明1 : 本人才疏學淺,用郭德綱的話說“我是一個小學生”,如有錯誤,歡迎討論,請勿謾罵^_^。
  • 聲     明2 : 原創博客請在轉載時保留原文鏈接或在文章開頭加上本人博客地址,否則保留追究法律責任的權利。
 
您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...