最近被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檔案中,隨程式一起啟動,我把這個分享出來,希望可以幫助更多的人,
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/3.html
標籤:ASP.NET