目录

简介

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

简洁实用Socket框架DotNettySocket的更多相关文章

  1. 写自己的Socket框架(一)

    本系列仅介绍可用于生产环境的C#异步Socket框架,如果您在其他地方看到类似的代码,不要惊讶,那可能就是我在参考开源代码时,直接“剽窃”过来的. 1.在脑海里思考一下整个socket的链接的处理流程 ...

  2. ZYSocket 4.3.5 SOCKET框架组 发布[NEW]

    最新代码请到 github: https://github.com/luyikk/ZYSOCKET 更新 4.3.5更新说明: 修复各种BUG. 重写了一份 protobuf-net 有什么用呢,不需 ...

  3. atitit.软件开发--socket框架选型--netty vs mina j

    atitit.软件开发--socket框架选型--netty vs mina j . Netty是由JBOSS提供的一个java开源框架 Apache mina 三.文档比较 mina文档多,,, 好 ...

  4. linux可用的跨平台C# .net standard2.0 写的高性能socket框架

    能在window(IOCP)/linux(epoll)运行,基于C# .net standard2.0 写的socket框架,可使用于.net Framework/dotnet core程序集,.使用 ...

  5. Workerman:PHP的socket框架

    hi,我们今天来讲讲Workerman,什么是Workerman呢? 看看官网上的介绍 Workerman是一款开源高性能异步PHP socket框架.支持高并发,超高稳定性,被广泛的用于手机app. ...

  6. 《Unity 3D游戏客户端基础框架》多线程异步 Socket 框架构建

    引言: 之前写过一个 demo 案例大致讲解了 Socket 通信的过程,并和自建的服务器完成连接和简单的数据通信,详细的内容可以查看 Unity3D -- Socket通信(C#).但是在实际项目应 ...

  7. 写自己的Socket框架(三)

    在通信写完了以后,应用层接收到Socket抛上来的byte[],这个时候对于实际的写逻辑的开发者来说,这样的数据并不友好,我们就需要在应用层统一一个包的规则(应用层协议),处理完以后,然后再传给实际的 ...

  8. 写自己的socket框架(二)

    1.开始正常监听以后,就要开始接受数据了,整体流程图如下: 2.上一节看到我们在程序初始化的时候,初始化了很多个SocketConnection,用于管理客户端的链接,那应用层如何来操作,又什么时候来 ...

  9. 一款很便捷很实用的框架——vue.js

    Hello,大家好!今天给大家带来一款十分好用的框架--vue.js! Vue.js是一套构建用户界面的渐进式框架.它 只关注视图层, 采用自底向上增量开发的设计. Vue 的目标是通过尽可能简单的 ...

随机推荐

  1. Vue技术点整理-Vue CLI

    Vue CLI 是一个基于 Vue.js 进行项目快速开发的脚手架 注:具体安装步骤可参考Vue CLI,默认安装的脚手架,是没有service.util等工具类的,以下主要描述如何在脚手架的基础上进 ...

  2. tomcat 启动窗口 名称 中文乱码

  3. 花5分钟时间来了解一下高性能网关Kong会有意外收获

    前言 前几天开源发布了 Kong.Net 项目,收到了大量园友的反馈,开源当天就突破了 100 个star ,可喜可贺,但是从侧面也说明,我们 .NetCore 阵营真的非常需要拥抱开源,应该敞开心扉 ...

  4. WINDOWS 安装ZeroMQ

    zmq看起来很好用,但是安装起来不是一般麻烦.原来以为java绑定会提供jar包直接可使用,但是官网没有提供已经编译好的库文件和jar.多么的不方便啊!最终还是要自己动手编译! 安装java版本的zm ...

  5. python基础认识(一)

    这些日子以来,新闻铺天盖地的都是人工智能,那么借着这股潮流,python也随之火起来了,现在的python不仅仅可以进行人工智能领域的开发.还可以进行web.爬虫等领域的运用.因此,我认为作为一个紧跟 ...

  6. 自定义ApplicationContextInitializer接口实现

    简介 ApplicationContextInitializer是Spring框架提供的接口, 该接口的主要功能就是在接口ConfigurableApplicationContext刷新之前,允许用户 ...

  7. 【DFS练习】Pku1950 Dessert-C++

    这道题和这道题很类似. 这里还是说一下坑点,因为前一道题'等式'的加数只有9个,但是这道题目最大到了15,所以在选择不加符号的时候需要判断是用100去乘还是用10去乘就可以了. 基本代码稍微把相关的9 ...

  8. redux、react-redux、redux-thunk、redux-saga使用及dva对比

    一.redux使用 Redux的核心概念其实很简单:将需要修改的state都存入到store里,发起一个action用来描述发生了什么,用reducers描述action如何改变state tree ...

  9. [原创]实现MongoDB数据库审计SQL语句的脚本

    功能:实现具体显示mongodb数据库表操作语句的状态和情况,使用awk和shell实现抓取和分析处理.脚本内容如下: #!/bin/bash if [ $# == 0 ];then echo &qu ...

  10. Golang 高效实践之并发实践context篇

    前言 在上篇Golang高效实践之并发实践channel篇中我给大家介绍了Golang并发模型,详细的介绍了channel的用法,和用select管理channel.比如说我们可以用channel来控 ...