在大部分Web系統中,我們可能遇到需要向客戶端推送消息的需求。SuperWebSocket第三方庫能讓我們輕松的完成任務。SuperWebSocket第三方庫可以從網上下載,不過通過Visual Studio Nuget安裝更快。
引用SuperWebSocket相關組件后,在項目中添加WebSocketManager類
using SuperWebSocket; using System; using System.Collections.Generic; using System.Linq; using System.Net; using System.Text; using System.Text.RegularExpressions; using System.Threading.Tasks; namespace WebSocketDemo { public static class WebSocketManager { static Dictionary<string, WebSocketSession> sessionDics = new Dictionary<string, WebSocketSession>(); static WebSocketServer webSocketServer; public static void Init() { var ip = GetLocalIP(); webSocketServer = new WebSocketServer(); var isSetup = webSocketServer.Setup(ip, 2019); Common.LogHelper.WriteError("WebSocketManager: 服務器端啟動" + (isSetup ? "成功" : "失敗")); if (!isSetup) return; webSocketServer.NewSessionConnected += WebSocketServer_NewSessionConnected; webSocketServer.SessionClosed += WebSocketServer_SessionClosed; webSocketServer.NewMessageReceived += WebSocketServer_NewMessageReceived; var isStart = webSocketServer.Start(); Common.LogHelper.WriteError("WebSocketManager: 服務器端偵聽" + (isStart ? "成功" : "失敗")); } /// <summary> /// 接收消息 /// </summary> /// <param name="session"></param> /// <param name="value"></param> private static void WebSocketServer_NewMessageReceived(WebSocketSession session, string value) { Common.LogHelper.WriteError("WebSocketManager: 接收消息 \r\n" + value); if (!string.IsNullOrWhiteSpace(value)) { if (!sessionDics.ContainsKey(value)) sessionDics.Add(value, session); else sessionDics[value] = session; } } /// <summary> /// 下線 /// </summary> /// <param name="session"></param> /// <param name="value"></param> private static void WebSocketServer_SessionClosed(WebSocketSession session, SuperSocket.SocketBase.CloseReason value) { Common.LogHelper.WriteError(string.Format("WebSocketManager:{0} {1}下線", value, session.RemoteEndPoint)); } /// <summary> /// 上線 /// </summary> /// <param name="session"></param> private static void WebSocketServer_NewSessionConnected(WebSocketSession session) { Common.LogHelper.WriteError(string.Format("WebSocketManager:{0}上線",session.RemoteEndPoint)); } /// <summary> /// 發送消息到客戶端 /// </summary> /// <param name="value"></param> /// <param name="msg"></param> public static void SendMsgToRemotePoint(string value, string msg) { if (sessionDics.ContainsKey(value)) { var webSocketSession = sessionDics[value]; if (webSocketSession != null) { webSocketSession.Send(msg); } } } /// <summary> /// 獲取本地IP等信息 /// </summary> /// <returns></returns> public static string GetLocalIP() { //本機IP地址 string strLocalIP = ""; //得到計算機名 string strPcName = Dns.GetHostName(); //得到本機IP地址數組 IPHostEntry ipEntry = Dns.GetHostEntry(strPcName); //遍歷數組 foreach (var IPadd in ipEntry.AddressList) { //判斷當前字符串是否為正確IP地址 if (IsRightIP(IPadd.ToString())) { //得到本地IP地址 strLocalIP = IPadd.ToString(); //結束循環 break; } } //返回本地IP地址 return strLocalIP; } /// <summary> /// 判斷是否為正確的IP地址 /// </summary> /// <param name="strIPadd">需要判斷的字符串</param> /// <returns>true = 是 false = 否</returns> private static bool IsRightIP(string strIPadd) { //利用正則表達式判斷字符串是否符合IPv4格式 if (Regex.IsMatch(strIPadd, "[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}")) { //根據小數點分拆字符串 string[] ips = strIPadd.Split('.'); if (ips.Length == 4 || ips.Length == 6) { //如果符合IPv4規則 if (System.Int32.Parse(ips[0]) < 256 && System.Int32.Parse(ips[1]) < 256 & System.Int32.Parse(ips[2]) < 256 & System.Int32.Parse(ips[3]) < 256) //正確 return true; //如果不符合 else //錯誤 return false; } else //錯誤 return false; } else //錯誤 return false; } } }
在Global.asax.cs下初始化WebSocket,並啟動。
public class WebApiApplication : System.Web.HttpApplication { protected void Application_Start() { AreaRegistration.RegisterAllAreas(); GlobalConfiguration.Configure(WebApiConfig.Register); FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters); RouteConfig.RegisterRoutes(RouteTable.Routes); BundleConfig.RegisterBundles(BundleTable.Bundles); WebSocketManager.Init(); } }
前端連接服務端WebSocket,打開網頁調用此js方法,就可以和服務端建立長連接通信。
WebSocketConnent(){
var ip= localStorage.getItem("IP");//服務端的IP
var openId= localStorage.getItem("kmWechatOpenId");//value
var url="ws://"+ip+":2019";
var ws;
if ("WebSocket" in window) {
ws = new WebSocket(url);
}
else if ("MozWebSocket" in window) {
ws = new MozWebSocket(url);
}
else{
console.log("WebSocketConnent","瀏覽器版本過低,請升級您的瀏覽器")
}
//注冊各類回調
ws.onopen = function () {
ws.send(openId);//服務端WebSocketServer_NewMessageReceived 接收到消息
console.log("WebSocketConnent","連接服務器成功");
}
ws.onclose = function () {
console.log("WebSocketConnent","與服務器斷開連接");
}
ws.onerror = function () {
console.log("WebSocketConnent","數據傳輸發生錯誤");
}
ws.onmessage = function (receiveMsg) {
localStorage.removeItem("token");//服務端SendMsgToRemotePoint 發送消息后接收
console.log("WebSocketConnent","服務器推送過來的消息:"+receiveMsg.data);
}
},