简洁实用Socket框架DotNettySocket
目录
简介
dotnettysocket是一个.net跨平台socket框架(支持.net4.5+及.net standard2.0+),同时支持tcpsocket、websocket和udpsocket,其基于微软强大的dotnetty框架,力求为socket通讯提供简单、高效、优雅的操作方式。
安装方式:nuget安装dotnettysocket即可
项目地址:https://github.com/coldairarrow/dotnettysocket
产生背景
两年前最开始接触物联网的时候,需要用到tcp及udp通讯,为了方便使用,将原始的socket进行了简单的封装,基本满足了需求,并将框架开源。但是由于精力及实力有限,没有进一步优化原框架。后来发现了强大的dotnetty框架,dotnetty是微软azure团队开源基于java netty框架的移植版,其性能优异、维护团队强大,许多.net强大的框架都使用它。dotnetty功能强大,但是用起来还是不够简洁(或许是个人感觉),刚好最近项目需要用到websocket,因此鄙人抽时间基于dotnetty进行简单封装了下,撸出一个力求简单、高效、优雅的socket框架。
使用方式
tcpsocket
tcp是面向连接的,所以服务端对连接的管理就至关重要,框架支持各种事件的处理、给连接设置连接名(身份标识)、通过连接名找到特定连接、连接收发数据、分包、粘包处理。
- 服务端
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
websocket与tcpsocket接口基本保持一致,仅有的区别就是tcpsocket支持字节的收发并且需要自行处理分包粘包。而websocket直接收发字符串(utf-8)编码,并且无需考虑分包粘包。框架目前没有支持wss,建议解决方案是使用nginx转发即可(相关资料一搜便有)
- 服务端
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>
udpsocket
udp天生便是收发一体的,以下分为服务端与客户端仅仅是为了方便理解
- 服务端
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); } } } }
结尾
以上所有示例在源码中都有,若觉得不错请点赞加星星,希望能够帮助到大家。
有任何问题请及时反馈或加群交流
qq群1:(已满)
qq群2:579202910
上一篇: Android开发,如何知道Wi-Fi已连接了一个热点
下一篇: 缺钱吗?随便拿