为什么推荐Kestrel作为网络开发框架
为什么推荐Kestrel
网络框架千千万万,在dotnet平台,我们可以直接手撸Socket,也可以基于dotnetty来开发,或者选择某些第三方类似于dotnetty的网络库,为何我要推荐Kestrel呢?
1 使用框架
网络编程是简单的,简单到大概就 new Socket(),Send()发送数据,Receive()接收数据,这大概是初学者的大致感受。
网络编程是复杂的,让Send()和Receive()稳定工作,花了老夫一年时间,每让服务器的性能提高10%又各花老夫两年时间,这大概是手撸过Socket的大哥的感受。
网络编程是抽象的传输层加高效的缓冲区管理,我们需要把它提升到框架来,而不能停留在原始的Socket工具级别。这大概是我从dotnetty和kestrel里悟出的道理。
2 框架的支撑者
选择某个框架,咱首先要看看这个这个框架背后的支撑者的力量。Kestrel是asp.netcore的Server部分,如果asp.netcore说它是dotnet平台上第二出名的应用框架,那没其它框架敢说第一是自己。我们可以通过commits来查看有哪些大牛在孜孜不倦地维护kestrel,其中@JamesNK、@BrennanConroy、@davidfowl等世界级大牛一直很活跃。反观其它网络框架,只有少量的社区力量甚至作者单个人的力量在贡献。
3 Kestrel的影响
三流的框架在自诩,二流的框架在吸取新鲜技术的养分,一流的框架在推动相关领域技术前行。
3.1 推动System.Net.Socket
在dotnet core 2.0或以前,Kestrel使用Libuv取代dotnet的Socket来操作网络,因为彼时dotnet的Socket性能,要比Libuv要差一些,特别在unix上的表现。也正是因为asp.netcore的kestrel对Socket性能有强烈的需求,在2.1时runtime层开始对Socket的性能大力改进,Task和ValueTask的异步发送和接收内部实现融入了SocketAsyncEventArgs,Socket甚至为NetworkStream开了路灯,让Socket与Libuv的性能直接平级。
3.2 推动System.IO.Pipelines
Pipelines诞生于.NET Core团队为使Kestrel成为业内最快的Web服务器之一所做的工作。最初是Kestrel内部的一个实现细节,后来发展成为一个可重用的API,它在dotnet coreapp 2.1 中作为一流的 BCL API(System.IO.Pipelines)提供给所有 .NET 开发人员。
正确解析来自Stream或Socket的数据的工作其实非常复杂,沉长和复杂的代码让人难以阅读和维护。再加上要实现高性能这条要求的话,就让人更加吐血,而Pipelines旨在解决这种复杂性。
有关Pipelines的好,我就不班门弄斧了,这是@davidfowl写的Pipelines介绍。
3.3 对普通开发者的影响
曾经一个小小SocketAwaitableEventArgs class,让多少开发者眼前一亮,惊叹无比。这不,现在已经不是最初实现了ICriticalNotifyCompletion接口了,转为实现了IValueTaskSource<SocketOperationResult>
,大家慢慢品吧。
4 Kestrel的魅力
4.1 单应用层多传输层
支持一个应用监听多个端口,每个端口走不同传输层,最后到达同一个应用协议层。比如下面的配置,传输层分别是tcp和tls over tcp,应用层都是http,不管是哪种传输最终都是被我们的application层统一处理http,简称殊途同归。
"Kestrel": {
"Endpoints": {
"http": {
"Url": "http://localhost:5000"
},
"https": {
"Url": "https://localhost:5001"
}
},
"Certificates": {
"Default": {
"Path": "",
"Password": ""
}
}
}
4.2 单传输层多应用层
我们也可以使用某个监听端口对应的传输层,分支不同的路由来实现多个应用协议application。常见的比如kestrel使用websocket做传输层,应用协议层为mqtt或signalr等。
// Mqtt over WebSocket
app.MapConnectionHandler<MqttConnectionHandler>("/mqtt");
// SingalR over Websocket
app.MapHub<SingalRHub>("/signalr");
4.3 自定义应用层
我们这里说所的应用层协议,往往是我们在这层协议上构建了业务,而不拿它来做传输协议,而实际中,一种协议往往即可以做广义的传输协议,也可以直接做构建业务的应用层协议(典型的WebSocket,甚至http也可以做传输协议)。在asp.netcore中,SingalR就是典型的一个不太复杂的应用层协议(相对http),我们也可以基于kestrel来开发telnet over tcp的服务,telnet做为应用层,tcp做传输层。
public class TelnetConnectionHandler : ConnectionHandler
{
/// <summary>
/// 收到Telnet连接后
/// </summary>
/// <param name="connection"></param>
/// <returns></returns>
public override async Task OnConnectedAsync(ConnectionContext connection)
{
var input = connection.Transport.Input;
var output = connection.Transport.Output;
// 从input解析telnet协议
...
}
}
public static class ListenOptionsExtensions
{
/// <summary>
/// 使用TelnetConnectionHandler
/// </summary>
/// <param name="listen"></param>
public static void UseTelnet(this ListenOptions listen)
{
listen.UseConnectionHandler<TelnetConnectionHandler>();
}
}
var section = context.Configuration.GetSection("Kestrel");
kestrel.Configure(section).Endpoint("Telnet", endpoint => endpoint.ListenOptions.UseTelnet());
4.4 增加传输层
假设我们需要telnet应用增加支持tls安全传输,我们可以再增加一个Telnets
的EndPoint。在telnet协议之前插入https(实际准确是的叫tls)中间件。现在不管是未加密的telnet请求还是tls加密的telnet请求,我们的应用层TelnetConnectionHandler
都能收到telnet请求内容。
var section = context.Configuration.GetSection("Kestrel");
kestrel.Configure(section).Endpoint("Telnets", endpoint => endpoint.ListenOptions.UseHttps().UseTelnet());
4.5 自定义传输层
在Stream设计模式里,往往需要开发TransportStream,其包装原始Stream且在自身的Read/Write方法里做必要的数据解码/编码操作,比如SslStream(Stream inner)
,向SSlStream写入[1,2,3,4]的数据,实际上是向inner Stream写入了[1,2,3,4]加密后的数据。
Kestrel的传输层是IDuplexPipe
类型的抽象对象,我们可以把IDuplexPipe对象转换为Stream对象,然后与既有的Stream套娃模式结合,再把最后的Stream转为IDuplexPipe
类型,替换到kestrel的连接对象的传输层。
这是一个高阶但不太常用的功能,想了解更多可以查看KestrelApp.Transforms
这个项目示例。
5 如何学习Kesrel
为了大家能学习Kestrel,我在github上开源了一个kestrel开发综合示例项目。
喜欢拿代码说话的同学,可以直接食用;喜欢理论指导行动的同学,可以先慢慢看项目上的文档链接,然后再一步步慢慢深入。
项目地址: https://github.com/xljiulang/KestrelApp
为什么推荐Kestrel作为网络开发框架的更多相关文章
- Linux学习笔记——重点推荐的Linux网络在线学习资源
首先非常感谢百度,感谢网络的搜索引擎技术,也非常感谢学习资源的贡献者和组织! 1:http://billie66.github.io/TLCL/book/zh/ 2:http://www.ha97. ...
- 转:Android开源项目推荐之「网络请求哪家强」 Android开源项目推荐之「网络请求哪家强」
转载自https://zhuanlan.zhihu.com/p/21879931 1. 原则 本篇说的网络请求专指 http 请求,在选择一个框架之前,我个人有个习惯,就是我喜欢选择专注的库,其实在软 ...
- Android框架之网络开发框架Volley
1. Volley简单介绍 我们平时在开发Android应用的时候不可避免地都须要用到网络技术.而多数情况下应用程序都会使用HTTP协议来发送和接收网络数据.Android系统中主要提供了两种方式来进 ...
- nodejs的精简型和全栈型开发框架介绍
总体来说你可以将Node.js开发框架归结为两类: - 精简型框架 - 全栈型框架 下面我们就对这两种框架进行探讨. 精简型框架 精简型框架提供的是最基本的功能和APIs,这类框架本身就是被设计成用来 ...
- Android okHttp网络请求之Get/Post请求
前言: 之前项目中一直使用的Xutils开源框架,从xutils 2.1.5版本使用到最近的xutils 3.0,使用起来也是蛮方便的,只不过最近想着完善一下app中使用的开源框架,由于Xutils里 ...
- iOS网络-03-NSURLSession与NSURLSessionTask
简介 NSURLSession也能完成网络请求 NSURLConnection在iOS9中不推荐使用,NSURLSession是iOS9中推荐使用的网络请求方式 NSURLSession需要与NSUR ...
- muduo网络库使用心得
上个月看了朋友推荐的mudo网络库,下完代码得知是国内同行的开源作品,甚是敬佩.下了mudo使用手冊和035版的代码看了下结构,感觉是一个比較成熟并且方便使用的网络库.本人手头也有自己的网络库,尽管不 ...
- UNIX网络编程 卷2:进程间通信
这篇是计算机类的优质预售推荐>>>><UNIX网络编程 卷2:进程间通信(第2版)> UNIX和网络专家W. Richard Stevens的传世之作 编辑推荐 两 ...
- 最流行的Node.js应用开发框架简介
最流行的Node.js应用开发框架简介 快速开发而又容易扩展,高性能且鲁棒性强.Node.js的出现让所有网络应用开发者的这些梦想成为现实.但是,有如其他新的开发语言技术一样,从头开始使用Node.j ...
- 当今最流行的Node.js应用开发框架简介
快速开发而又容易扩展,高性能且鲁棒性强.Node.js的出现让所有网络应用开发者的这些梦想成为现实.但是,有如其他新的开发语言技术一样,从头开始使用Node.js的最基本功能来编写代码构建应用是一个非 ...
随机推荐
- Pod 的生命周期
上图展示了一个 Pod 的完整生命周期过程,其中包含 Init Container.Pod Hook.健康检查 三个主要部分,接下来我们就来分别介绍影响 Pod 生命周期的部分: 首先在介绍 Pod ...
- KubeOperator界面,集群详情中的存储,存储提供商
点击"添加",假设选择的类型是rook-ceph,表示的是在这个k8s集群里创建rook-ceph集群,而不是显示已经存在的集群 意味着可以使用这种办法在k8s集群里创建rook- ...
- 使用Filebeat传送多行日志
文章转载自:https://blog.csdn.net/UbuntuTouch/article/details/106272704 在解决应用程序问题时,多行日志为开发人员提供了宝贵的信息. 堆栈跟踪 ...
- MHA架构的实现方式
转载自:https://www.linuxprobe.com/centos7-mha-mysql5.html 安装mysql5.7,并配置好主从复制 第一:安装mysql57,并关闭防火墙 yum i ...
- Allure的简单使用
Allure的简单使用 1.Allure简介 简单的理解下,可以把Allure当成一个用于生成美观测试报告的开源工具,配合Pytest测试框架使用更佳. 也就是说,Allure是在Pytest执行测试 ...
- 移动端Vant组件库REM适配
REM适配 基础配置 在页面布局之前,对REM进行配置,以适配移动端特点. 官方参考 Vant文档---->快速上手---->进阶用法---->Rem适配----> Vant ...
- 微信支付更新功能,商户转账到零钱 php版 (2022-10-12更新)
<?php class WechatMerchantTransfer { /** * @notes 商家转账到零钱 * @param $batch_no //提现订单号 * @param $le ...
- 齐博x1.2万能参数配置接口
为何叫做万能参数接口,那是因为可以随意设置后台哪些字段可以给接口使用,还可以无限的新增接口参数,这个参数不仅仅是一个开关或文字,还可以是一张图片.一组图片.一组菜单.一个视频地址等等,非常的灵活. h ...
- grpc错误处理
0.1.索引 https://waterflow.link/articles/1665938704477 我们都知道当发起http请求的时候,服务端会返回一些http状态码,不管是成功还是失败.客户端 ...
- 日志处理logging
前言 什么是日志?有什么作用?日志是跟踪软件运行时所发生的事件的一种方法,简单来说它可以记录某时某刻运行了什么代码,当出现问题时可以方便我们进行定位. 由python内置了一个logging模块,用户 ...