C# 數據推送 實時數據推送 輕量級消息訂閱發布 多級消息推送 分布式推送
前言
本文將使用一個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# 數據推送 實時數據推送 輕量級消息訂閱發布 多級消息推送 分布式推送