超轻量级、支持插件的 .NET 网络通信框架
前言
给大家推荐一个轻量级的、支持插件的综合网络通信库:TouchSocket。
TouchSocket 的基础通信功能包括 TCP、UDP、SSL、RPC 和 HTTP。其中,HTTP 服务器支持 WebSocket、静态网页、XML-RPC、WebAPI 和 JSON-RPC 等扩展插件。
此外,TouchSocket 还支持自定义协议的 TouchRPC,具备 SSL 加密、异步调用、权限管理、错误状态返回、服务回调和分布式调用等功能。
在空载函数执行时,10 万次调用仅需 3.8 秒;在不返回状态时,仅需 0.9 秒。
项目介绍
TouchSocket(Pro)是基于 .NET 的程序集系列,可用于对应 .NET 版本的 C#、F# 和 VB.NET 项目。无论你的项目是控制台、WinForms、WPF 还是 ASP.NET Core,它都全面支持。
TouchSocket(Pro)长期支持 .NET 4.5、.NET 4.8.1、.NET Standard 2.0 三个平台,并将 .NET 6.0 作为最新稳定版支持平台,同时支持.NET 7.0 作为最新发布平台。

项目环境
.NET 4.5:保证了在.Net Framework上的最低支持版本。基本上支持全系99%的功能。
.NET 4.8.1:这是在net45的依赖基础之上,额外添加了一些微软官方库,以支持达到net6.0一样的功能(例如:Span、ValueTuple、ValueTask等)。
.NET Standard 2.0:这是保证了在一些通用平台上的最低依赖。基本上支持全系99%的功能。
.NET 6.0:这是目前最新的稳定版发布平台,它在最低依赖的前提下,还保证了全部功能。
.NET 7.0:这是目前最新的发布平台,我们会在该平台上开发最能尝鲜的功能(例如:AOT等)。
支持框架的框架Console、WPF、Winform、Blazor Server、Xamarin、MAUI、Avalonia、Mono、Unity 3D(除WebGL)、其他(即所有C#系)
项目功能
1、功能导图

2、项目文档

项目特点
1、传统 IOCP 与 TouchSocket 的 IOCP 模式
TouchSocket 的 IOCP 模式与传统 IOCP 不同。以微软官方示例为例,传统 IOCP 使用 MemoryBuffer 开辟一块内存,均分后给每个会话分配一个区域接收数据,收到数据后再复制并处理。而 TouchSocket 则在每次接收前从内存池中获取一个可用内存块直接用于接收,收到数据后直接处理该内存块,从而避免了复制操作。虽然这只是细节上的设计差异,但在传输 10 万次 64KB 数据时,性能提升了 10 倍。
2、数据处理适配器
TouchSocket 在设计时借鉴了其他产品的优秀理念,数据处理适配器就是其中之一。与其他产品不同的是,TouchSocket 的适配器功能更加强大、易用且灵活。它不仅可以提前解析数据包,还可以解析数据对象,并且可以随时替换,立即生效。例如,可以使用固定包头对数据进行预处理,从而解决数据分包和粘包问题;也可以直接解析 HTTP 数据协议和 WebSocket 数据协议等。
3、兼容性与适配
TouchSocket 提供多种框架模型,能够完全兼容基于 TCP 和 UDP 协议的所有协议。例如,TcpService 和 TcpClient 的基础功能与 Socket 相同,但增强了框架的坚固性和并发性,通过事件形式抛出连接和接收数据,使用户能够更加友好地使用。
项目使用
1、Nuget安装
搜索框输入TouchSocket,然后在搜索结果中选择,点击安装,具体如下图所示

2、TcpService
TcpService是Tcp系服务器基类,它不参与实际的数据交互,只是配置、激活、管理、注销、重建SocketClient类实例。
而SocketClient是当TcpClient(客户端) 成功连接服务器以后,由服务器新建的一个实例类,后续的所有通信,也都是通过该实例完成的。
var service = new TcpService();
service.Connecting = (client, e) => { return EasyTask.CompletedTask; };//有客户端正在连接
service.Connected = (client, e) => { return EasyTask.CompletedTask; };//有客户端成功连接
service.Disconnecting = (client, e) => { return EasyTask.CompletedTask; };//有客户端正在断开连接,只有当主动断开时才有效。
service.Disconnected = (client, e) => { return EasyTask.CompletedTask; };//有客户端断开连接
service.Received = (client, e) =>
{
//从客户端收到信息
var mes = Encoding.UTF8.GetString(e.ByteBlock.Buffer, 0, e.ByteBlock.Len);//注意:数据长度是byteBlock.Len
client.Logger.Info($"已从{client.Id}接收到信息:{mes}");
client.Send(mes);//将收到的信息直接返回给发送方
//client.Send("id",mes);//将收到的信息返回给特定ID的客户端
//将收到的信息返回给在线的所有客户端。
//注意:这里只是一个建议思路,实际上群发应该使用生产者消费者模式设计
//var ids = service.GetIds();
//foreach (var clientId in ids)
//{
// if (clientId != client.Id)//不给自己发
// {
// service.Send(clientId, mes);
// }
//}
return EasyTask.CompletedTask;
};
service.Setup(new TouchSocketConfig()//载入配置
.SetListenIPHosts("tcp://127.0.0.1:7789", 7790)//同时监听两个地址
.ConfigureContainer(a =>//容器的配置顺序应该在最前面
{
a.AddConsoleLogger();//添加一个控制台日志注入(注意:在maui中控制台日志不可用)
})
.ConfigurePlugins(a =>
{
//a.Add();//此处可以添加插件
}));
service.Start();//启动
3、TcpClient
TcpClient是Tcp系客户端基类,他直接参与tcp的连接、发送、接收、处理、断开等,他的业务与服务器的SocketClient是一一对应的。
var tcpClient = new TcpClient();
tcpClient.Connecting = (client, e) => { return EasyTask.CompletedTask; };//即将连接到服务器,此时已经创建socket,但是还未建立tcp
tcpClient.Connected = (client, e) => {return EasyTask.CompletedTask; };//成功连接到服务器
tcpClient.Disconnecting = (client, e) => {return EasyTask.CompletedTask; };//即将从服务器断开连接。此处仅主动断开才有效。
tcpClient.Disconnected = (client, e) => {return EasyTask.CompletedTask; };//从服务器断开连接,当连接不成功时不会触发。
tcpClient.Received = (client, e) =>
{
//从服务器收到信息。但是一般byteBlock和requestInfo会根据适配器呈现不同的值。
var mes = Encoding.UTF8.GetString(e.ByteBlock.Buffer, 0, e.ByteBlock.Len);
tcpClient.Logger.Info($"客户端接收到信息:{mes}");
return EasyTask.CompletedTask;
};
//载入配置
tcpClient.Setup(new TouchSocketConfig()
.SetRemoteIPHost("127.0.0.1:7789")
.ConfigureContainer(a =>
{
a.AddConsoleLogger();//添加一个日志注入
}));
tcpClient.Connect();//调用连接,当连接不成功时,会抛出异常。
//Result result = tcpClient.TryConnect();//或者可以调用TryConnect
//if (result.IsSuccess())
//{
//}
tcpClient.Logger.Info("客户端成功连接");
tcpClient.Send("RRQM");
4、TcpClient 断线重连
在Config的插件配置中,使用重连插件即可。
.ConfigurePlugins(a=>
{
a.UseReconnection(5, true, 1000);//如需永远尝试连接,tryCount设置为-1即可。
});
项目案例
1、工程师软件工具箱
使用TouchRpc开发的一个内部工程师软件工具箱 。



2、远程监控、控制项目


项目地址
GitHub:https://github.com/RRQM/TouchSocket
Gitee:https://gitee.com/RRQM_Home/TouchSocket
最后
如果你觉得这篇文章对你有帮助,不妨点个赞支持一下!你的支持是我继续分享知识的动力。如果有任何疑问或需要进一步的帮助,欢迎随时留言。
也可以加入微信公众号[DotNet技术匠] 社区,与其他热爱技术的同行一起交流心得,共同成长!优秀是一种习惯,欢迎大家留言学习!

超轻量级、支持插件的 .NET 网络通信框架的更多相关文章
- 解读超轻量级DI容器-Guice与Spring框架的区别【转载】
依赖注入,DI(Dependency Injection),它的作用自然不必多说,提及DI容器,例如spring,picoContainer,EJB容器等等,近日,google诞生了更轻巧的DI容器… ...
- 腾讯正式开源高性能超轻量级 PHP 框架 Biny
概况 Biny是一款高性能的超轻量级PHP框架 遵循 MVC 模式,用于快速开发现代 Web 应用程序 Biny代码简洁优雅,对应用层,数据层,模板渲染层的封装简单易懂,能够快速上手使用 高性能,框架 ...
- c#网络通信框架networkcomms内核解析之十 支持优先级的自定义线程池
NetworkComms网络通信框架序言 本例基于networkcomms2.3.1开源版本 gplv3协议 如果networkcomms是一顶皇冠,那么CommsThreadPool(自定义线程池 ...
- 开源基于asio的网络通信框架asio2,支持TCP,UDP,HTTP,RPC,SSL,跨平台,支持可靠UDP,支持TCP自动拆包,TCP数据报模式等
开源基于asio的网络通信框架asio2,支持TCP,UDP,HTTP,RPC,SSL,跨平台,支持可靠UDP,支持TCP自动拆包,TCP数据报模式等 C++开发网络通信程序时用asio是个不错的选择 ...
- [热拔插] 轻量级Winform插件式框架
写在前面的话 对于大神,Winform这种“古董玩具”,实在没太多“技术性”可言了,然而『好用才是王道』,本文不以技术为卖点,纯属经验之谈,欢迎交流拍砖 朴素版UI 开发初衷 由于本人所在公司不定时需 ...
- 成熟的C#网络通信框架介绍——ESFramework通信框架
(转自:http://www.cnblogs.com/zhuweisky/archive/2010/08/12/1798211.html) ESFramework通信框架是一套性能卓越.稳定可靠.强大 ...
- 网络通信框架Retrofit2
网络通信框架Retrofit2 1 概要 Retrofit2的简介以及特点 Retrofit2使用配置(导包,权限等) Retrofit2中常用的注解介绍 Retrofit2实现http网络访问 GE ...
- 13个可实现超棒数据可视化效果的Javascript框架
随着商业及其相关需求的发展,数据成为越来越重要的元素之一,为了更加直观和明显的展示商业潜在的趋势和内在的特性,我们需要使用图表和图形的方式来直观动态的展示数据内在秘密,在今天的这篇文章中我们推荐12款 ...
- Android网络通信框架LiteHttp2.0 开篇简介和大纲目录
本帖最后由 移动天宇 于 2015-10-26 10:42 编辑 LiteHttp2.0很多东东焕然一新,旧的能力也得到增强,没有使用的同学来了解一下吧. Android网络框架为什么可以选用lite ...
- 【转】ESFramework成熟的C#网络通信框架(跨平台)
原文地址:http://www.cnblogs.com/zhuweisky/archive/2010/08/12/1798211.html ESFramework网络通信框架是一套性能卓越.稳定可靠. ...
随机推荐
- 深度学习论文翻译解析(二十三):Segment Angthing
论文标题:Segment Angthing 论文作者: Alexander Kirillov Eric Mintun Nikhila Ravi Hanzi Mao... 论文地址:2304.02 ...
- 解决方案 | 在 Tkinter 中导入 pywinauto/pyautogui 时窗口大小发生变化
上面问题也可以换一个说法,pywinauto/pyautogui 时改变了tkinter的原有的窗口大小.这个问题困扰了我好几天而且网上有这样的问题但是并没有答案,今天摸索出答案给大家分享下.解决方法 ...
- 解决方案 | Chrome/Edge 总是自动修改我的pdf默认打开方式
1.问题描述 最近我的pdf文件总是被chrome打开(如图1),而且点击属性,更改别的pdf阅读器也不管用(如图2),此时的chrome就像个流氓软件一样. 图1 被chrome劫持 图2 点击属性 ...
- PAT-1003 我要通过! (20分) JavaScript(node)
"答案正确"是自动判题系统给出的最令人欢喜的回复.本题属于 PAT 的"答案正确"大派送 -- 只要读入的字符串满足下列条件,系统就输出"答案正确&q ...
- [oeasy]python0074[专业选修]字节序_byte_order_struct_pack_大端序_小端序
进制转化 回忆上次内容 上次 总结了 计算字符串值的函数 eval 四种进制的转化函数 bin oct int hex 函数名 前缀 目标字符串所用进制 bin 0b 二进制 oct 0o ...
- 机器学习:详解迁移学习(Transfer learning)
详解迁移学习 深度学习中,最强大的理念之一就是,有的时候神经网络可以从一个任务中习得知识,并将这些知识应用到另一个独立的任务中.所以例如,也许已经训练好一个神经网络,能够识别像猫这样的对象,然后使用那 ...
- [MRCTF2020]Ezpop(反序列化)
打开题目即可得源码 Welcome to index.php <?php //flag is in flag.php //WTF IS THIS? //Learn From https://ct ...
- 学习笔记--Java中static关键字
Java中static关键字 static基础用法 什么时候成员变量声明为实例变量 所有对象的这个属性随对象而变化 什么时候成员变量声明为静态变量 所有对象都是这个属性 静态变量在类加载的时候初始化, ...
- 在.NET Web API设置响应输出Json数据格式常用的两种方式
前言 在ASP.NET Core Web API中设置响应输出Json数据格式常用以下两种方式:可以通过添加System.Text.Json或Newtonsoft.JsonJSON序列化和反序列化库在 ...
- 用了组合式 (Composition) API 后代码变得更乱了,怎么办?
前言 组合式 (Composition) API 的一大特点是"非常灵活",但也因为非常灵活,每个开发都有自己的想法.加上项目的持续迭代导致我们的代码变得愈发混乱,最终到达无法维护 ...