C# 實現 websocket 服務器 發送客戶端網頁前端數據,C#和網頁前端通信


今天的文章來說明如何在C#里構建我們自己的websocket服務器,已經客戶端,以及如何發送數據給客戶端,如何實現訂閱的操作,如何實現應答模式的操作。ok,廢話不多說,直接進入正題:

 

本庫的demo源代碼地址:https://github.com/dathlin/HslCommunication

如果想要聯系作者,請訪問官網:  http://www.hslcommunication.cn/

 

聯系作者及加群方式:http://www.hslcommunication.cn/Cooperation 

 

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

 

1
Install-Package HslCommunication

  

 如果需要教程:Nuget安裝教程:http://www.cnblogs.com/dathlin/p/7705014.html

 

using HslCommunication.WebSocket;
using HslCommunication;

  

測試的websocket服務端界面如下:

 

 

 我們的客戶端如下的信息:

 

 

 

好了,我們來學習如何開發websocket的服務器,其實很簡單,實例化,啟動服務器就可以了。就好比下面的代碼,綁定了一個事件的回調地址,我們把數據顯示出來即可

        private WebSocketServer wsServer;

        private void button1_Click( object sender, EventArgs e )
        {
            try
            {
                wsServer = new WebSocketServer( );
                wsServer.OnClientApplicationMessageReceive += WebSocket_OnClientApplicationMessageReceive;
                wsServer.ServerStart( 1883 );
                MessageBox.Show( "Start Success" );
            }
            catch (Exception ex)
            {
                MessageBox.Show( "Start Failed : " + ex.Message );
            }
        }
        private void WebSocket_OnClientApplicationMessageReceive( WebSocketSession session, WebSocketMessage message )
        {
            Invoke( new Action( ( ) =>
            {
                if(!isStop)
                    textBox8.AppendText( $"OpCode:[{message.OpCode}] Mask:[{message.HasMask}] Payload:[{Encoding.UTF8.GetString( message.Payload )}]" + Environment.NewLine );
            } ) );
            }
        }

 

我們新增一個按鈕,用來發送數據到客戶端的

wsServer.PublishAllClientPayload( "測試的數據信息" );

好了,我們目前可以測試了

 

 

客戶端收到了數據內容,我們現在來看看,是否推送給了網頁端,為此我們需要編寫一個簡單的網頁。新建一個html文件,打開記事本,寫入下面的代碼

<!DOCTYPE HTML>
<html>
   <head>
   <meta charset="utf-8">
   <title>hsl websocket測試</title>
      <script type="text/javascript">
         function WebSocketTest()
         {
            if ("WebSocket" in window)
            {
               // 打開一個 web socket
               var ws = new WebSocket("ws://127.0.0.1:1883");
               ws.onopen = function()
               {
                  console.log("已經打開...");
               };
               ws.onmessage = function (evt) 
               { 
                  var received_msg = evt.data;
                  console.log(received_msg);
               };
            }
            
            else
            {
				console.log("您的瀏覽器不支持 WebSocket!");
            }
         }
      </script>
   </head>
   <body>
      <div id="sse">
         <a href="javascript:WebSocketTest()">運行 WebSocket</a>
      </div>
      
   </body>
</html>

  

 然后我們運行起來,我這使用了谷歌的瀏覽器運行了這個網頁的信息。

 

 

當然了,客戶端和網頁也可以直接發送數據給C#的服務器后台。我們現在看看web端的數據是如何發送的

ws.send("發送數據");

  我們看到發送數據非常的簡單。

 

我們已經看過了web端的數據通信方式,我們再來看看C#端的客戶端是如何操作的

		private WebSocketClient wsClient;

		private void button1_Click( object sender, EventArgs e )
		{
			wsClient = new WebSocketClient( "127.0.0.1", 1883 );
              wsClient.OnClientApplicationMessageReceive += WebSocket_OnWebSocketMessageReceived; OperateResult connect = wsClient.ConnectServer( ); if (connect.IsSuccess) { MessageBox.Show( StringResources.Language.ConnectServerSuccess ); } else { MessageBox.Show( connect.Message ); } } private void WebSocket_OnWebSocketMessageReceived( WebSocketMessage message ) { try { Invoke( new Action( ( ) => { string msg = Encoding.UTF8.GetString( message.Payload ); textBox8.AppendText( msg + Environment.NewLine ); } ) ); } catch { } }

客戶端發送數據也是很簡單的。

		private void button3_Click( object sender, EventArgs e )
		{
			OperateResult send = wsClient.SendServer(  textBox4.Text );

			if (!send.IsSuccess) MessageBox.Show( "Send Failed:" + send.Message );
		}

  

 

 

講完了上述,再來講講訂閱。從websocket協議來看,其實沒有訂閱的功能,這個都是二次開發實現的。在hsl的服務器中,允許客戶端請求的時候攜帶header,來表示當前的訂閱信息。

比如我想訂閱A,那么header就要增加 

HslSubscribes: A

  

服務器端就可以使用下面的方法來發布訂閱操作了

wsServer.PublishClientPayload( "A", "1234" );

  

就會只給當前訂閱的客戶端發送數據。當然這種方式比較不好,無法動態調整訂閱的信息,而且對於web端原生的websocket,也不太好集成、那我們可以使用二次開發的方式實現。比如服務器端,根據客戶端發來的數據進行動態添加訂閱。

		private void WebSocket_OnClientApplicationMessageReceive( WebSocketSession session, WebSocketMessage message )
		{
			Invoke( new Action( ( ) =>
			{
				if(!isStop)
					textBox8.AppendText( $"OpCode:[{message.OpCode}] Mask:[{message.HasMask}] Payload:[{Encoding.UTF8.GetString( message.Payload )}]" + Environment.NewLine );
			} ) );

			// 假設發來的數據是訂閱的主題。那我們可以動態添加
			session.AddTopic( Encoding.UTF8.GetString( message.Payload ) );

		}

  

當然也可以動態移除,需要對payload數據進行約定了。好了,最后介紹下,同步訪問機制。hsl的websocket支持同步訪問機制,客戶端在標記自己的請求為同步訪問后。服務器端發布數據的時候自動過濾所有的同步客戶端。同步客戶端的意思是,客戶端發送數據給客戶端,並等待服務器的返回。

		private void WebSocket_OnClientApplicationMessageReceive( WebSocketSession session, WebSocketMessage message )
		{
			Invoke( new Action( ( ) =>
			{
				if(!isStop)
					textBox8.AppendText( $"OpCode:[{message.OpCode}] Mask:[{message.HasMask}] Payload:[{Encoding.UTF8.GetString( message.Payload )}]" + Environment.NewLine );
			} ) );

			// 應答客戶端連接的情況下是需要進行返回數據的,此處演示返回的是原始的數據,追加一個隨機數,你可以自己根據業務來決定返回什么數據
			if (session.IsQASession)
			{
				wsServer.SendClientPayload( session, Encoding.UTF8.GetString( message.Payload ) + random.Next( 1000, 10000 ) );
			}
		}

  

此處的示例就是

		private void WebSocket_OnClientApplicationMessageReceive( WebSocketSession session, WebSocketMessage message )
		{
			Invoke( new Action( ( ) =>
			{
				if(!isStop)
					textBox8.AppendText( $"OpCode:[{message.OpCode}] Mask:[{message.HasMask}] Payload:[{Encoding.UTF8.GetString( message.Payload )}]" + Environment.NewLine );
			} ) );

			// 應答客戶端連接的情況下是需要進行返回數據的,此處演示返回的是原始的數據,追加一個隨機數,你可以自己根據業務來決定返回什么數據
			if (session.IsQASession)
			{
				wsServer.SendClientPayload( session, Encoding.UTF8.GetString( message.Payload ) + random.Next( 1000, 10000 ) );
			}
		}

 

當然了,你也可以直接認定所有的客戶端,都是同步網絡。這樣的話,就不需要判斷了、

		private void WebSocket_OnClientApplicationMessageReceive( WebSocketSession session, WebSocketMessage message )
		{
			Invoke( new Action( ( ) =>
			{
				if(!isStop)
					textBox8.AppendText( $"OpCode:[{message.OpCode}] Mask:[{message.HasMask}] Payload:[{Encoding.UTF8.GetString( message.Payload )}]" + Environment.NewLine );
			} ) );

			// 應答客戶端連接的情況下是需要進行返回數據的,此處演示返回的是原始的數據,追加一個隨機數,你可以自己根據業務來決定返回什么數據
			//if (session.IsQASession)
			//{
				wsServer.SendClientPayload( session, Encoding.UTF8.GetString( message.Payload ) + random.Next( 1000, 10000 ) );
			//}
		}

  

實際看業務需求了。

我們來看看同步的客戶端操作

		private WebSocketQANet wsClient;

		private void button1_Click( object sender, EventArgs e )
		{
			wsClient = new WebSocketQANet( "127.0.0.1", 1883 );
			OperateResult connect = wsClient.ConnectServer( );
			if (connect.IsSuccess)
			{
				MessageBox.Show( StringResources.Language.ConnectServerSuccess );
			}
			else
			{
				MessageBox.Show( StringResources.Language.ConnectedFailed + connect.ToMessageShowString( ) );
			}
		}

  

 

然后就可以直接訪問了

			OperateResult<string> read = wsClient.ReadFromServer(  "123" );

			if (read.IsSuccess)
			{
				string msg = read.Content;
                        }
                        else
                        {
                            // 失敗
                        }

  

好了,更多的詳細內容可以參考demo源代碼哦。感謝支持

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM