DotNettySocket是一個.NET跨平臺Socket框架(支持.NET4.5+及.NET Standard2.0+),同時支持TcpSocket、WebSocket和UdpSocket,其基於微軟強大的DotNetty框架,力求爲Socket通信提供簡單、高效、優雅的操做方式。javascript
安裝方式:Nuget安裝DotNettySocket便可html
項目地址:https://github.com/Coldairarrow/DotNettySocketjava
兩年前最開始接觸物聯網的時候,須要用到Tcp及Udp通信,爲了方便使用,將原始的Socket進行了簡單的封裝,基本知足了需求,並將框架開源。可是因爲精力及實力有限,沒有進一步優化原框架。後來發現了強大的DotNetty框架,DotNetty是微軟Azure團隊開源基於Java Netty框架的移植版,其性能優異、維護團隊強大,許多.NET強大的框架都使用它。DotNetty功能強大,可是用起來仍是不夠簡潔(或許是我的感受),恰好最近項目須要用到WebSocket,所以鄙人抽時間基於DotNetty進行簡單封裝了下,擼出一個力求簡單、高效、優雅的Socket框架。git
Tcp是面向鏈接的,因此服務端對鏈接的管理就相當重要,框架支持各類事件的處理、給鏈接設置鏈接名(身份標識)、經過鏈接名找到特定鏈接、鏈接收發數據、分包、粘包處理。github
using Coldairarrow.DotNettySocket; using System; using System.Text; using System.Threading.Tasks; namespace TcpSocket.Server { class Program { static async Task Main(string[] args) { var theServer = await SocketBuilderFactory.GetTcpSocketServerBuilder(6001) .SetLengthFieldEncoder(2) .SetLengthFieldDecoder(ushort.MaxValue, 0, 2, 0, 2) .OnConnectionClose((server, connection) => { Console.WriteLine($"鏈接關閉,鏈接名[{connection.ConnectionName}],當前鏈接數:{server.GetConnectionCount()}"); }) .OnException(ex => { Console.WriteLine($"服務端異常:{ex.Message}"); }) .OnNewConnection((server, connection) => { connection.ConnectionName = $"名字{connection.ConnectionId}"; Console.WriteLine($"新的鏈接:{connection.ConnectionName},當前鏈接數:{server.GetConnectionCount()}"); }) .OnRecieve((server, connection, bytes) => { Console.WriteLine($"服務端:數據{Encoding.UTF8.GetString(bytes)}"); connection.Send(bytes); }) .OnSend((server, connection, bytes) => { Console.WriteLine($"向鏈接名[{connection.ConnectionName}]發送數據:{Encoding.UTF8.GetString(bytes)}"); }) .OnServerStarted(server => { Console.WriteLine($"服務啓動"); }).BuildAsync(); Console.ReadLine(); } } }
using Coldairarrow.DotNettySocket; using System; using System.Net; using System.Text; using System.Threading.Tasks; namespace UdpSocket.Client { class Program { static async Task Main(string[] args) { var theClient = await SocketBuilderFactory.GetUdpSocketBuilder() .OnClose(server => { Console.WriteLine($"客戶端關閉"); }) .OnException(ex => { Console.WriteLine($"客戶端異常:{ex.Message}"); }) .OnRecieve((server, point, bytes) => { Console.WriteLine($"客戶端:收到來自[{point.ToString()}]數據:{Encoding.UTF8.GetString(bytes)}"); }) .OnSend((server, point, bytes) => { Console.WriteLine($"客戶端發送數據:目標[{point.ToString()}]數據:{Encoding.UTF8.GetString(bytes)}"); }) .OnStarted(server => { Console.WriteLine($"客戶端啓動"); }).BuildAsync(); while (true) { await theClient.Send(Guid.NewGuid().ToString(), new IPEndPoint(IPAddress.Parse("127.0.0.1"), 6003)); await Task.Delay(1000); } } } }
WebSocket與TcpSocket接口基本保持一致,僅有的區別就是TcpSocket支持字節的收發而且須要自行處理分包粘包。而WebSocket直接收發字符串(UTF-8)編碼,而且無需考慮分包粘包。框架目前沒有支持WSS,建議解決方案是使用Nginx轉發便可(相關資料一搜便有)web
using Coldairarrow.DotNettySocket; using System; using System.Threading.Tasks; namespace WebSocket.Server { class Program { static async Task Main(string[] args) { var theServer = await SocketBuilderFactory.GetWebSocketServerBuilder(6002) .OnConnectionClose((server, connection) => { Console.WriteLine($"鏈接關閉,鏈接名[{connection.ConnectionName}],當前鏈接數:{server.GetConnectionCount()}"); }) .OnException(ex => { Console.WriteLine($"服務端異常:{ex.Message}"); }) .OnNewConnection((server, connection) => { connection.ConnectionName = $"名字{connection.ConnectionId}"; Console.WriteLine($"新的鏈接:{connection.ConnectionName},當前鏈接數:{server.GetConnectionCount()}"); }) .OnRecieve((server, connection, msg) => { Console.WriteLine($"服務端:數據{msg}"); connection.Send(msg); }) .OnSend((server, connection, msg) => { Console.WriteLine($"向鏈接名[{connection.ConnectionName}]發送數據:{msg}"); }) .OnServerStarted(server => { Console.WriteLine($"服務啓動"); }).BuildAsync(); Console.ReadLine(); } } }
using Coldairarrow.DotNettySocket; using System; using System.Threading.Tasks; namespace WebSocket.ConsoleClient { class Program { static async Task Main(string[] args) { var theClient = await SocketBuilderFactory.GetWebSocketClientBuilder("127.0.0.1", 6002) .OnClientStarted(client => { Console.WriteLine($"客戶端啓動"); }) .OnClientClose(client => { Console.WriteLine($"客戶端關閉"); }) .OnException(ex => { Console.WriteLine($"異常:{ex.Message}"); }) .OnRecieve((client, msg) => { Console.WriteLine($"客戶端:收到數據:{msg}"); }) .OnSend((client, msg) => { Console.WriteLine($"客戶端:發送數據:{msg}"); }) .BuildAsync(); while (true) { await theClient.Send(Guid.NewGuid().ToString()); await Task.Delay(1000); } } } }
<!DOCTYPE HTML> <html> <head> <meta charset="utf-8"> <title>菜鳥教程(runoob.com)</title> <script type="text/javascript"> function WebSocketTest() { if ("WebSocket" in window) { var ws = new WebSocket("ws://127.0.0.1:6002"); ws.onopen = function () { console.log('連上服務端'); setInterval(function () { ws.send("111111"); }, 1000); }; ws.onmessage = function (evt) { var received_msg = evt.data; console.log('收到' + received_msg); }; ws.onclose = function () { console.log("鏈接已關閉..."); }; } else { alert("您的瀏覽器不支持 WebSocket!"); } } </script> </head> <body> <div id="sse"> <a href="javascript:WebSocketTest()">運行 WebSocket</a> </div> </body> </html>
Udp天生即是收發一體的,如下分爲服務端與客戶端僅僅是爲了方便理解c#
using Coldairarrow.DotNettySocket; using System; using System.Text; using System.Threading.Tasks; namespace UdpSocket.Server { class Program { static async Task Main(string[] args) { var theServer = await SocketBuilderFactory.GetUdpSocketBuilder(6003) .OnClose(server => { Console.WriteLine($"服務端關閉"); }) .OnException(ex => { Console.WriteLine($"服務端異常:{ex.Message}"); }) .OnRecieve((server, point, bytes) => { Console.WriteLine($"服務端:收到來自[{point.ToString()}]數據:{Encoding.UTF8.GetString(bytes)}"); server.Send(bytes, point); }) .OnSend((server, point, bytes) => { Console.WriteLine($"服務端發送數據:目標[{point.ToString()}]數據:{Encoding.UTF8.GetString(bytes)}"); }) .OnStarted(server => { Console.WriteLine($"服務端啓動"); }).BuildAsync(); Console.ReadLine(); } } }
using Coldairarrow.DotNettySocket; using System; using System.Net; using System.Text; using System.Threading.Tasks; namespace UdpSocket.Client { class Program { static async Task Main(string[] args) { var theClient = await SocketBuilderFactory.GetUdpSocketBuilder() .OnClose(server => { Console.WriteLine($"客戶端關閉"); }) .OnException(ex => { Console.WriteLine($"客戶端異常:{ex.Message}"); }) .OnRecieve((server, point, bytes) => { Console.WriteLine($"客戶端:收到來自[{point.ToString()}]數據:{Encoding.UTF8.GetString(bytes)}"); }) .OnSend((server, point, bytes) => { Console.WriteLine($"客戶端發送數據:目標[{point.ToString()}]數據:{Encoding.UTF8.GetString(bytes)}"); }) .OnStarted(server => { Console.WriteLine($"客戶端啓動"); }).BuildAsync(); while (true) { await theClient.Send(Guid.NewGuid().ToString(), new IPEndPoint(IPAddress.Parse("127.0.0.1"), 6003)); await Task.Delay(1000); } } } }
以上全部示例在源碼中都有,若以爲不錯請點贊加星星,但願可以幫助到你們。瀏覽器
有任何問題請及時反饋或加羣交流websocket
QQ羣1:(已滿)框架
QQ羣2:579202910