请选择 进入手机版 | 继续访问电脑版

马上加入IBC程序猿 各种源码随意下,各种教程随便看! 注册 每日签到 加入编程讨论群

C#教程 ASP.NET教程 C#视频教程程序源码享受不尽 C#问题入口 ASP.NET问题入口

【C#问题提交】 社群合作 申请版主 程序开发 【远程协助】 每天乐一乐 每日签到 【承接毕业设计】 面试-葵花宝典下载

官方一群:

官方二群:

查看: 89|回复: 0

简洁实用Socket框架DotNettySocket

[复制链接]
  • TA的每日心情
    开心
    昨天 09:42
  • 签到天数: 1446 天

    [LV.10]以坛为家III

    926

    主题

    2828

    帖子

    9万

    积分

    管理员

    IBC编程社区-原道楠

    Rank: 9Rank: 9Rank: 9

    积分
    92121

    推广达人突出贡献优秀版主荣誉管理论坛元老

    发表于 2019-8-13 17:50:36 | 显示全部楼层 |阅读模式

    马上加入IBC,查看更多教程

    您需要 登录 才可以下载或查看,没有帐号?立即注册

    x

    目录

    • 简介
    • 产生背景
    • 使用方式
      • TcpSocket
      • WebSocket
      • UdpSocket
    • 结尾

    简介

    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是面向连接的,所以服务端对连接的管理就至关重要,框架支持各种事件的处理、给连接设置连接名(身份标识)、通过连接名找到特定连接、连接收发数据、分包、粘包处理。

    • 服务端
    1. <code>using Coldairarrow.DotNettySocket;
    2. using System;
    3. using System.Text;
    4. using System.Threading.Tasks;
    5. namespace TcpSocket.Server
    6. {
    7. class Program
    8. {
    9. static async Task Main(string[] args)
    10. {
    11. var theServer = await SocketBuilderFactory.GetTcpSocketServerBuilder(6001)
    12. .SetLengthFieldEncoder(2)
    13. .SetLengthFieldDecoder(ushort.MaxValue, 0, 2, 0, 2)
    14. .OnConnectionClose((server, connection) =>
    15. {
    16. Console.WriteLine($"连接关闭,连接名[{connection.ConnectionName}],当前连接数:{server.GetConnectionCount()}");
    17. })
    18. .OnException(ex =>
    19. {
    20. Console.WriteLine($"服务端异常:{ex.Message}");
    21. })
    22. .OnNewConnection((server, connection) =>
    23. {
    24. connection.ConnectionName = $"名字{connection.ConnectionId}";
    25. Console.WriteLine($"新的连接:{connection.ConnectionName},当前连接数:{server.GetConnectionCount()}");
    26. })
    27. .OnRecieve((server, connection, bytes) =>
    28. {
    29. Console.WriteLine($"服务端:数据{Encoding.UTF8.GetString(bytes)}");
    30. connection.Send(bytes);
    31. })
    32. .OnSend((server, connection, bytes) =>
    33. {
    34. Console.WriteLine($"向连接名[{connection.ConnectionName}]发送数据:{Encoding.UTF8.GetString(bytes)}");
    35. })
    36. .OnServerStarted(server =>
    37. {
    38. Console.WriteLine($"服务启动");
    39. }).BuildAsync();
    40. Console.ReadLine();
    41. }
    42. }
    43. }</code>
    复制代码
    • 客户端
    1. <code>using Coldairarrow.DotNettySocket;
    2. using System;
    3. using System.Net;
    4. using System.Text;
    5. using System.Threading.Tasks;
    6. namespace UdpSocket.Client
    7. {
    8. class Program
    9. {
    10. static async Task Main(string[] args)
    11. {
    12. var theClient = await SocketBuilderFactory.GetUdpSocketBuilder()
    13. .OnClose(server =>
    14. {
    15. Console.WriteLine($"客户端关闭");
    16. })
    17. .OnException(ex =>
    18. {
    19. Console.WriteLine($"客户端异常:{ex.Message}");
    20. })
    21. .OnRecieve((server, point, bytes) =>
    22. {
    23. Console.WriteLine($"客户端:收到来自[{point.ToString()}]数据:{Encoding.UTF8.GetString(bytes)}");
    24. })
    25. .OnSend((server, point, bytes) =>
    26. {
    27. Console.WriteLine($"客户端发送数据:目标[{point.ToString()}]数据:{Encoding.UTF8.GetString(bytes)}");
    28. })
    29. .OnStarted(server =>
    30. {
    31. Console.WriteLine($"客户端启动");
    32. }).BuildAsync();
    33. while (true)
    34. {
    35. await theClient.Send(Guid.NewGuid().ToString(), new IPEndPoint(IPAddress.Parse("127.0.0.1"), 6003));
    36. await Task.Delay(1000);
    37. }
    38. }
    39. }
    40. }
    41. </code>
    复制代码

    WebSocket

    WebSocket与TcpSocket接口基本保持一致,仅有的区别就是TcpSocket支持字节的收发并且需要自行处理分包粘包。而WebSocket直接收发字符串(UTF-8)编码,并且无需考虑分包粘包。框架目前没有支持WSS,建议解决方案是使用Nginx转发即可(相关资料一搜便有)

    • 服务端
    1. <code>using Coldairarrow.DotNettySocket;
    2. using System;
    3. using System.Threading.Tasks;
    4. namespace WebSocket.Server
    5. {
    6. class Program
    7. {
    8. static async Task Main(string[] args)
    9. {
    10. var theServer = await SocketBuilderFactory.GetWebSocketServerBuilder(6002)
    11. .OnConnectionClose((server, connection) =>
    12. {
    13. Console.WriteLine($"连接关闭,连接名[{connection.ConnectionName}],当前连接数:{server.GetConnectionCount()}");
    14. })
    15. .OnException(ex =>
    16. {
    17. Console.WriteLine($"服务端异常:{ex.Message}");
    18. })
    19. .OnNewConnection((server, connection) =>
    20. {
    21. connection.ConnectionName = $"名字{connection.ConnectionId}";
    22. Console.WriteLine($"新的连接:{connection.ConnectionName},当前连接数:{server.GetConnectionCount()}");
    23. })
    24. .OnRecieve((server, connection, msg) =>
    25. {
    26. Console.WriteLine($"服务端:数据{msg}");
    27. connection.Send(msg);
    28. })
    29. .OnSend((server, connection, msg) =>
    30. {
    31. Console.WriteLine($"向连接名[{connection.ConnectionName}]发送数据:{msg}");
    32. })
    33. .OnServerStarted(server =>
    34. {
    35. Console.WriteLine($"服务启动");
    36. }).BuildAsync();
    37. Console.ReadLine();
    38. }
    39. }
    40. }
    41. </code>
    复制代码
    • 控制台客户端
    1. <code>using Coldairarrow.DotNettySocket;
    2. using System;
    3. using System.Threading.Tasks;
    4. namespace WebSocket.ConsoleClient
    5. {
    6. class Program
    7. {
    8. static async Task Main(string[] args)
    9. {
    10. var theClient = await SocketBuilderFactory.GetWebSocketClientBuilder("127.0.0.1", 6002)
    11. .OnClientStarted(client =>
    12. {
    13. Console.WriteLine($"客户端启动");
    14. })
    15. .OnClientClose(client =>
    16. {
    17. Console.WriteLine($"客户端关闭");
    18. })
    19. .OnException(ex =>
    20. {
    21. Console.WriteLine($"异常:{ex.Message}");
    22. })
    23. .OnRecieve((client, msg) =>
    24. {
    25. Console.WriteLine($"客户端:收到数据:{msg}");
    26. })
    27. .OnSend((client, msg) =>
    28. {
    29. Console.WriteLine($"客户端:发送数据:{msg}");
    30. })
    31. .BuildAsync();
    32. while (true)
    33. {
    34. await theClient.Send(Guid.NewGuid().ToString());
    35. await Task.Delay(1000);
    36. }
    37. }
    38. }
    39. }</code>
    复制代码
    • 网页客户端
    1. <code><!DOCTYPE HTML>
    2. <html>
    3. <head>
    4. <meta charset="utf-8">
    5. <title>菜鸟教程(runoob.com)</title>
    6. <script type="text/javascript">
    7. function WebSocketTest() {
    8. if ("WebSocket" in window) {
    9. var ws = new WebSocket("ws://127.0.0.1:6002");
    10. ws.onopen = function () {
    11. console.log('连上服务端');
    12. setInterval(function () {
    13. ws.send("111111");
    14. }, 1000);
    15. };
    16. ws.onmessage = function (evt) {
    17. var received_msg = evt.data;
    18. console.log('收到' + received_msg);
    19. };
    20. ws.onclose = function () {
    21. console.log("连接已关闭...");
    22. };
    23. }
    24. else {
    25. alert("您的浏览器不支持 WebSocket!");
    26. }
    27. }
    28. </script>
    29. </head>
    30. <body>
    31. <div id="sse">
    32. <a href="javascript:WebSocketTest()">运行 WebSocket</a>
    33. </div>
    34. </body>
    35. </html></code>
    复制代码

    UdpSocket

    Udp天生便是收发一体的,以下分为服务端与客户端仅仅是为了方便理解

    • 服务端
    1. <code>using Coldairarrow.DotNettySocket;
    2. using System;
    3. using System.Text;
    4. using System.Threading.Tasks;
    5. namespace UdpSocket.Server
    6. {
    7. class Program
    8. {
    9. static async Task Main(string[] args)
    10. {
    11. var theServer = await SocketBuilderFactory.GetUdpSocketBuilder(6003)
    12. .OnClose(server =>
    13. {
    14. Console.WriteLine($"服务端关闭");
    15. })
    16. .OnException(ex =>
    17. {
    18. Console.WriteLine($"服务端异常:{ex.Message}");
    19. })
    20. .OnRecieve((server, point, bytes) =>
    21. {
    22. Console.WriteLine($"服务端:收到来自[{point.ToString()}]数据:{Encoding.UTF8.GetString(bytes)}");
    23. server.Send(bytes, point);
    24. })
    25. .OnSend((server, point, bytes) =>
    26. {
    27. Console.WriteLine($"服务端发送数据:目标[{point.ToString()}]数据:{Encoding.UTF8.GetString(bytes)}");
    28. })
    29. .OnStarted(server =>
    30. {
    31. Console.WriteLine($"服务端启动");
    32. }).BuildAsync();
    33. Console.ReadLine();
    34. }
    35. }
    36. }
    37. </code>
    复制代码
    • 客户端
    1. <code>using Coldairarrow.DotNettySocket;
    2. using System;
    3. using System.Net;
    4. using System.Text;
    5. using System.Threading.Tasks;
    6. namespace UdpSocket.Client
    7. {
    8. class Program
    9. {
    10. static async Task Main(string[] args)
    11. {
    12. var theClient = await SocketBuilderFactory.GetUdpSocketBuilder()
    13. .OnClose(server =>
    14. {
    15. Console.WriteLine($"客户端关闭");
    16. })
    17. .OnException(ex =>
    18. {
    19. Console.WriteLine($"客户端异常:{ex.Message}");
    20. })
    21. .OnRecieve((server, point, bytes) =>
    22. {
    23. Console.WriteLine($"客户端:收到来自[{point.ToString()}]数据:{Encoding.UTF8.GetString(bytes)}");
    24. })
    25. .OnSend((server, point, bytes) =>
    26. {
    27. Console.WriteLine($"客户端发送数据:目标[{point.ToString()}]数据:{Encoding.UTF8.GetString(bytes)}");
    28. })
    29. .OnStarted(server =>
    30. {
    31. Console.WriteLine($"客户端启动");
    32. }).BuildAsync();
    33. while (true)
    34. {
    35. await theClient.Send(Guid.NewGuid().ToString(), new IPEndPoint(IPAddress.Parse("127.0.0.1"), 6003));
    36. await Task.Delay(1000);
    37. }
    38. }
    39. }
    40. }
    41. </code>
    复制代码

    结尾

    以上所有示例在源码中都有,若觉得不错请点赞加星星,希望能够帮助到大家。

    有任何题目请及时反馈或加群交流

    QQ群1:(已满)

    QQ群2:579202910


    来源:https://www.cnblogs.com/coldairarrow/p/11336771.html
    免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则