1. 程式人生 > >C# 數據推送 實時數據推送 輕量級消息訂閱發布 多級消息推送 分布式推送

C# 數據推送 實時數據推送 輕量級消息訂閱發布 多級消息推送 分布式推送

特性 style 群聊 開始 AC 消息訂閱 進度 都在 多人

前言


本文將使用一個NuGet公開的組件技術來實現數據訂閱推送功能,由服務器進行推送數據,客戶端訂閱指定的數據後,即可以接收服務器推送過來的數據,包含了自動重連功能,使用非常方便

nuget地址:https://www.nuget.org/packages/HslCommunication/ 技術分享圖片 技術分享圖片

github地址:https://github.com/dathlin/HslCommunication 技術分享圖片 技術分享圖片 如果喜歡可以star或是fork,還可以打賞支持。

在Visual Studio 中的NuGet管理器中可以下載安裝,也可以直接在NuGet控制臺輸入下面的指令安裝:

Install-Package HslCommunication

NuGet安裝教程 http://www.cnblogs.com/dathlin/p/7705014.html

技術支持QQ群:592132877 (組件的版本更新細節也將第一時間在群裏發布)組件API地址:http://www.cnblogs.com/dathlin/p/7703805.html

訪問測試項目,客戶端和服務器的源代碼都在上面的地址裏


下面的一個項目是這個組件的訪問測試項目,您可以進行初步的訪問的測試,免去了您寫測試程序的麻煩,源代碼也在本文開始處的項目裏,

下載地址為:HslCommunicationDemo.zip

以下就是對服務器的指定關鍵字的數據的訂閱,服務器提供了幾個關鍵字訂閱,以供測試。

  • B 隨機數訂閱
  • C 時間訂閱
  • D JSON數據訂閱
  • E XML數據訂閱

技術分享圖片

如果該服務器不可用,請下載本地版本的服務器

PushNetServer.zip

技術分享圖片

特性支持


  • 支持數據廣播,按指定的關鍵字來廣播
  • 支持客戶端斷線重連
  • 支持服務器端簡單的監控
  • 支持日誌輸出
  • 服務器支持來自其他遠程的服務器數據輸入,形成數據推送網絡
  • 目前只支持字符串的數據推送,復雜的數據需要進行序列化,具體參照json推送和xml推送

引用


ModBus組件所有的功能類都在 HslCommunication.Enthernet

命名空間,所以再使用之前先添加

using HslCommunication.Enthernet;
using HslCommunication;

  

服務器端搭建


先進行聲明變量

private NetPushServer pushServer;

然後再一個啟動按鈕裏寫上如下的代碼

pushServer = new NetPushServer( );
pushServer.ServerStart( 12345 );

到這裏為止,服務器的代碼基本已經寫好了,短短的兩三行代碼而已。只是目前的數據並沒有數據推送功能。

一個經典的情景是什麽,比如你有一堆實時數據是從設備采集回來的,這些數據是在服務器上的。 你還有個客戶端的軟件,很多人同時在線,如果別人打開監控實時數據的話,就特別適用於本組件的方法,因為你走數據庫顯然是更慢的,而且對服務器壓力也大。采用本組件就可以完美的解決這件事情、

假設你采集了來自設備的數據,我們做個1秒鐘的定時器,然後啟動定時器,模擬每秒鐘的數據推送,推送什麽呢?先試試看隨機數

private Random random = new Random( ); // 先定義一個隨機數生成器

  

定時器的代碼如下:

pushServer.PushString( "A", random.Next( 1000, 10000 ).ToString( ) );

到這裏為止,服務器的一個完整的代碼已經寫完了。我們來看看客戶端怎麽寫

客戶端端搭建


先進行聲明變量

private NetPushClient pushClient;

實例化,需要指定服務器的IP和端口,還有想訂閱的關鍵字

pushClient = new NetPushClient( "127.0.0.1", 12345, "A" );

接下來就是創建訂閱了,需要指定一個調用的委托,會返回一個是否成功的信號,因為有可能網絡的原因,有可能因為沒有這個關鍵字,會導致創建失敗。

OperateResult create = pushClient.CreatePush( new Action<NetPushClient, string>( PushFromServer ) );
            if (create.IsSuccess)
            {
                MessageBox.Show( "成功" );
            }
            else
            {
                MessageBox.Show( "失敗:" + create.Message );
            }

上面使用了一個委托,PushFromServer的方法如下,主要是使用委托把數據顯示出來:

private void PushFromServer( NetPushClient pushClient, string data )
        {
            if (IsHandleCreated) Invoke( new Action<string>( m =>
              {
                  label8.Text = DateTime.Now.ToString( "yyyy-MM-dd HH:mm:ss.fff" ); // 顯示接收時間
                  receiveCount++;
                  label9.Text = receiveCount.ToString( );  // 顯示接收次數
                  textBox4.Text = m;  // 數據最終顯示在這裏
              } ), data );
        }

在相應的窗口關閉之前,關閉掉客戶端就可以了。如果不手動關閉,當你關閉窗口的時候,該連接很有可能仍然存在。

pushClient.ClosePush( );

  

一個簡單的完整的數據訂閱功能已經完成了。

復雜數據訂閱


上面的代碼只能推送字符串數據,怎麽樣實現推送復雜的數據呢,我們假設有4個數據,需要同時推送給客戶端。那我們可以選擇2種方式,一種是json,一種是xml,各有優缺點

JSON

            JObject json = new JObject( );
            json.Add( "value1", new JValue( random.Next( 1000, 9999 ) ) );
            json.Add( "value2", new JValue( Math.Round( random.NextDouble( ), 6 ) * 1000 ));
            json.Add( "value3", new JValue( Guid.NewGuid( ).ToString( ) ) );
            json.Add( "value4", new JValue( DateTime.Now ) );

            pushServer.PushString( textBox14.Text, json.ToString( ) );

Xml

            XElement element = new XElement( "Data" );
            element.SetElementValue( "value1", random.Next( 1000, 9999 ) );
            element.SetElementValue( "value2", (Math.Round( random.NextDouble( ), 6 ) * 1000 ).ToString() );
            element.SetElementValue( "value3", Guid.NewGuid( ).ToString( ) );
            element.SetElementValue( "value4", DateTime.Now.ToString( "O" ) );

            pushServer.PushString( textBox18.Text, element.ToString( ) );

解析的時候按照對應的信息解析即可。

令牌設置


服務器支持令牌設置,如果客戶端無法提供一致的令牌校驗,就會被拒絕連接,提升系統的安全性

pushServer.Token = new Guid( "04f6e588-4b9c-4dfb-86b2-4389742534b5" );  

客戶端就需要設置相同的令牌才能登陸服務器,從而進行數據校驗。

日誌輸出


pushServer.LogNet = new HslCommunication.LogNet.LogNetSingle( "log.txt" );       // 支持日誌

  

監控在線客戶端數量


有一個屬性是標識服務器端在線的所有客戶端的數量,方便的系統進行監控

pushServer.OnlineCount

星形數據網絡


上面演示的都是手動推送的服務器數據,或是寫代碼采集設備來實現自動推送,如果想做分布式的數據推送,或是緩解服務器的數據推送,那麽可以按照如下做

技術分享圖片

就是說,由一個主服務器將數據推到2個子服務器,再由子服務器將數據推送給客戶端

對於主服務和推送客戶端代碼不需要任何改變,主要是加一層中間服務器,也是NetPushServer類,子服務器的數據需要來自手動,只需要手動加一行代碼即可

OperateResult create = pushServer.CreatePushRemote( "127.0.0.1", 12345, "A" );

                if(create.IsSuccess)
                {
                    MessageBox.Show( "創建成功!" );
                }
                else
                {
                    MessageBox.Show( "創建失敗!" + create.Message );
                }

意思就是這個子服務器訂閱了另一個主服務器的關鍵字A的數據,並實時推給了其他在線的客戶端。

熟悉這個原理後,就可以構建一個高性能的數據推送網絡服務。

動態關鍵字


以上的操作都是靜態的關鍵字推送,推送的數據都是大家都有的,如何推送一個專門的客戶端呢?也可以實現,稍微復雜一點,先通過另一個網絡來約定一個共同的唯一的關鍵字,比如GUID碼,然後已這個碼作為關鍵字推送。

另一種交互網絡可以參考:http://www.cnblogs.com/dathlin/p/7697782.html

這種情況適用什麽例子呢,,,,比如你向服務器弄了個請求,這個請求可能很久,你也不知道服務器什麽時候能完成,需要一個百分比顯示服務器進度的時候,就需要動態關鍵字了,服務器操作的過程只需要向唯一的關鍵字推送進度即可。

如果有什麽問題,可以加群聊。

C# 數據推送 實時數據推送 輕量級消息訂閱發布 多級消息推送 分布式推送