当前位置: 移动技术网 > IT编程>开发语言>c# > 简洁实用Socket框架DotNettySocket

简洁实用Socket框架DotNettySocket

2019年08月12日  | 移动技术网IT编程  | 我要评论

目录

简介

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

如对本文有疑问, 点击进行留言回复!!

相关文章:

验证码:
移动技术网