最近被websocket的一個問題困擾了很久,有一個需求是在web網站中搭建websocket服務。客戶端通過網頁與伺服器建立連接,然後伺服器根據ip給客戶端網頁發送信息。 其實,這個需求並不難,只是剛開始對websocket的內容不太瞭解。上網搜索了一下,有通過asp.net core 實現的,有 ...
最近被websocket的一個問題困擾了很久,有一個需求是在web網站中搭建websocket服務。客戶端通過網頁與伺服器建立連接,然後伺服器根據ip給客戶端網頁發送信息。
其實,這個需求並不難,只是剛開始對websocket的內容不太瞭解。上網搜索了一下,有通過asp.net core 實現的,有通過一般處理程式ashx文件來實現的,這些方法不能滿足我當前網站的需求。
最後,通過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文件中,隨程式一起啟動。我把這個分享出來,希望可以幫助更多的人。