前言
有項目用到WebSocket,但是資源有限又不能用服務器,所以 做了個簡易的WebSocket通信.
本項目是用C#控制檯程序實現WebSocket服務,非服務器實現,非服務器實現,非服務器實現
步驟
- 創建空白 控制檯 程序 (不會的自行百度) .net Framework 至少需要4.0,因爲需要使用到System.Net.WebSockets.WebSocket
- 創建變量
/// <summary> /// HTTP監聽服務 /// </summary> private static HttpListener listener; /// <summary> /// 接收數組 /// </summary> private static ArraySegment<byte> reciveBufs = new ArraySegment<byte>(new byte[0xFFFF]); /// <summary> /// ws連接管理 /// </summary> private static List<WebSocket> clients = new List<WebSocket>();
- 異步監聽HTTP
listener = new HttpListener(); //打開HTTP服務 listener.Prefixes.Add("http://127.0.0.1:8080/"); //HTTP服務網址 listener.Start(); //開始監聽HTTP listener.BeginGetContext(Service, listener); //異步接收
使用 127.0.0.1:8080網址,此處可以跟據實際情況設定
- HTTP處理函數
var context = listener.EndGetContext(ar); //讀取 new Task(() => ProContext(context)).Start(); //新進程處理 listener.BeginGetContext(Service, listener); //繼續異步接收
- 處理WS連接函數
var wsContext = await context.AcceptWebSocketAsync(null); //獲取上下文 Console.WriteLine($"{DateTime.Now} - {context.Request.RemoteEndPoint} - WebSocket conected!"); //顯示有WS連接 (WS來者不據,可在此通過IP等篩選連接) using (var ws = wsContext.WebSocket) //使用using保證WS得到釋放 { clients.Add(ws); //管理WS連接 WebSocketReceiveResult wsdata; //接收結果變量 while (true) { try { wsdata = await ws.ReceiveAsync(reciveBufs, cancel); //接收數據 } catch {//接收失敗,退出連接 Console.WriteLine($"{DateTime.Now} - {context.Request.RemoteEndPoint} - out!"); clients.Remove(ws); //管理ws連接 break; } byte[] bRec = new byte[wsdata.Count]; //接收數組 Array.Copy(reciveBufs.Array, bRec, wsdata.Count); //保存接收數組 var sendStr = $"{context.Request.RemoteEndPoint} - {Encoding.UTF8.GetString(bRec)}"; //連接成String字符串 Console.WriteLine($"{DateTime.Now} - {sendStr}"); //顯示 var sendBufs = new ArraySegment<byte>(Encoding.UTF8.GetBytes(sendStr)); //轉換成需要發送給所有人的發送數組 clients.ForEach(o => { o.SendAsync(sendBufs, WebSocketMessageType.Text, true, cancel).Wait(); // 發送給所有人 }); } clients.Remove(ws); }
獲取到HTTP連接後,提出WS
var wsContext = await context.AcceptWebSocketAsync(null); //獲取上下文
-
循環接收WS信息
wsdata = await ws.ReceiveAsync(reciveBufs, cancel); //接收數據
接收到信息後轉換成字符串(跟據實際情況自行處理),然後轉發給所有WS連接
Encoding.UTF8.GetString(bRec)
clients.ForEach(o => { o.SendAsync(sendBufs, WebSocketMessageType.Text, true, cancel).Wait(); // 發送給所有人 });
- 編寫客戶端(在此編寫了控制檯程序和H5網頁,代碼可在文末自行下載)
- 控制檯客戶端測試控制檯客戶端發送Hello world!給服務器,服務器再轉發給客戶端
- H5網頁測試H5先連接,然後填寫發送信息,點擊發送後,所有連接的WS都能收到
- 水平有限,代碼未做深入出錯處理,各位大神可幫忙測試
- 附上代碼下載地址
-