asp.net網站作為websocket服務端的應用該如何寫


  最近被websocket的一個問題困擾了很久,有一個需求是在web網站中搭建websocket服務。客戶端通過網頁與服務器建立連接,然后服務器根據ip給客戶端網頁發送信息。

  其實,這個需求並不難,只是剛開始對websocket的內容不太了解。上網搜索了一下,有通過asp.net core 實現的、有通過一般處理程序ashx文件來實現的,這些方法不能滿足我當前網站的需求。我自己通過SignalR也實現了此功能,而且使用signalR實現起來會更簡單。但是我的需求是客戶端不是我編寫,而且是一個手持機,只給我留了一個填寫websocket服務器地址的地方,所以我沒有辦法通過signalR封裝的js去調用后台的websocket服務。如果你的需求不像我這么苛刻,你完全可以通過signalR實現,而且更加簡單。

  最后,通過fleck第三方庫實現了我想要的功能。下面詳細說一下我的實現過程。

  1.下載fleck第三方庫,我是通過Git下載的,源碼下載

   點擊頁面中的Clone or download -> Download ZIP,下載

   

  下載完之后,可以查看里面的文檔,具體的實現可以查看代碼。

 

  2.將fleck加入到自己的項目中,並對fleck進行引用。

  

 

  3.編寫我們自己的websocket類

using System;
using System.Collections.Generic;
using System.Configuration;
using System.Linq;
using System.Web;
using Fleck;

namespace FAW.Common
{
    public class WsContext
    {
        //客戶端url以及其對應的Socket對象字典
        static IDictionary<string, IWebSocketConnection> dic_Sockets = new Dictionary<string, IWebSocketConnection>();

        public static void StartUpWs()
        {
            String ipValue = ConfigurationManager.AppSettings["WebsocketAddress"];
            //創建
            //WebSocketServer server = new WebSocketServer("ws://127.0.0.1:8819/terver");//監聽所有的的地址
            WebSocketServer server = new WebSocketServer(ipValue);//監聽的地址寫在配置文件里
            //出錯后進行重啟
            server.RestartAfterListenError = true;

            //開始監聽
            server.Start(socket =>
            {
                socket.OnOpen = () =>   //連接建立事件
                {
                    //獲取客戶端網頁的url
                    string clientUrl = socket.ConnectionInfo.ClientIpAddress + ":" + socket.ConnectionInfo.ClientPort;
                    dic_Sockets.Add(clientUrl, socket);
                    LogManager.WriteLog("服務器:和客戶端網頁:[" + clientUrl + "] 建立WebSock連接!");
                };
                socket.OnClose = () =>  //連接關閉事件
                {
                    string clientUrl = socket.ConnectionInfo.ClientIpAddress + ":" + socket.ConnectionInfo.ClientPort;
                    //如果存在這個客戶端,那么對這個socket進行移除
                    if (dic_Sockets.ContainsKey(clientUrl))
                    {
                        //注:Fleck中有釋放
                        //關閉對象連接 
                        if (dic_Sockets[clientUrl] != null)
                        {
                            dic_Sockets[clientUrl].Close();
                        }
                        dic_Sockets.Remove(clientUrl);
                    }
                    LogManager.WriteLog("服務器:和客戶端網頁:[" + clientUrl + "]  斷開WebSock連接!");
                };
                socket.OnMessage = message =>  //接受客戶端網頁消息事件
                {
                    string clientUrl = socket.ConnectionInfo.ClientIpAddress + ":" + socket.ConnectionInfo.ClientPort;
                    LogManager.WriteLog("服務器:【收到】來客戶端網頁:" + clientUrl + "的信息:\n" + message);

                };
            });

        }

        public static void SendMsg(String ipAddress, String jsonString)
        {
            if (String.IsNullOrEmpty(jsonString))
            {
                //寫日志
                LogManager.WriteLog("中止發送,向客戶端發送信息為空。" );
                return;
            }
            foreach (var item in dic_Sockets.Values)
            {
                if (item.IsAvailable == true && item.ConnectionInfo.ClientIpAddress == ipAddress)
                {
                    LogManager.WriteLog("服務器: 向客戶端發送信息為 " + jsonString);
                    item.Send(jsonString);
                }
            }
        }
    }
}

 

  這段代碼呢,StartUpWs函數主要是建立一個websocket服務端,SendMsg函數是負責提供外部調用向指定的客戶端發送內容的工作。

            try
            {
                String pdaIP = cameraLogic.QueryPDAIPByIP(cameraIP);
                LogManager.WriteLog("獲取攝像頭對應的手機機IP:" + pdaIP);
                WsContext.SendMsg(pdaIP, sendMessage);
            }
            catch (Exception ex)
            {
                LogManager.WriteLog("手動抬桿websocket異常:" + ex.Message);
            }            

  這個代碼片段就是在網站中調用SendMsg函數,給指定的客戶端發送數據。

  注意:這里要提一點,如果websocket服務的端口要提供給外網訪問的話,需要將端口加入到防火牆入站規則中,並且需要做一下內外網ip和端口的映射,否則外網想訪問這個服務是不可以的。

  4.接下來我們就要將websocket添加到網站中,讓它隨着網站的啟動而啟動。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Routing;
using System.Web.Security;
using FAW.WEB;
using FAW.Common;

namespace FAW.WEB
{
    public class Global : HttpApplication
    {
        void Application_Start(object sender, EventArgs e)
        {
            // 在應用程序啟動時運行的代碼
            AuthConfig.RegisterOpenAuth();

            //建立websocket服務器
            WsContext.StartUpWs();
        }
        
    }
}

   這樣就可以了。

  5.測試websocket服務是否可用的話,可以通過websocket在線測試的功能。這個只要百度一下,你就全知道了,很簡單,這里不再介紹。

  總結:其實websocket的操作真的不難,就是普通的http請求得到了一次升級后,建立了一個全雙工的通道,可以相互發送信息。只是我在網上並沒有找到asp.net網站作為服務端的例子,其實需要做的只有兩步:1.建立一個websocket的服務端;2.將websocket的服務端加入到Global文件中,隨程序一起啟動。我把這個分享出來,希望可以幫助更多的人。

   

 


免責聲明!

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



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