为什么推荐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,简称殊途同归。

Copy
"Kestrel": { "Endpoints": { "http": { "Url": "http://localhost:5000" }, "https": { "Url": "https://localhost:5001" } }, "Certificates": { "Default": { "Path": "", "Password": "" } } }

4.2 单传输层多应用层#

我们也可以使用某个监听端口对应的传输层,分支不同的路由来实现多个应用协议application。常见的比如kestrel使用websocket做传输层,应用协议层为mqtt或signalr等。

Copy
// 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做传输层。

Copy
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协议 ... } }
Copy
public static class ListenOptionsExtensions { /// <summary> /// 使用TelnetConnectionHandler /// </summary> /// <param name="listen"></param> public static void UseTelnet(this ListenOptions listen) { listen.UseConnectionHandler<TelnetConnectionHandler>(); } }
Copy
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请求内容。

Copy
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 如何学习Kestrel#

为了大家能学习Kestrel,我在github上开源了一个kestrel开发综合示例项目。
喜欢拿代码说话的同学,可以直接食用;喜欢理论指导行动的同学,可以先慢慢看项目上的文档链接,然后再一步步慢慢深入。
项目地址: https://github.com/xljiulang/KestrelApp

posted @   jiulang  阅读(6580)  评论(34编辑  收藏  举报
相关博文:
阅读排行:
· 微软正式发布.NET 10 Preview 1:开启下一代开发框架新篇章
· 没有源码,如何修改代码逻辑?
· NetPad:一个.NET开源、跨平台的C#编辑器
· PowerShell开发游戏 · 打蜜蜂
· 在鹅厂做java开发是什么体验
点击右上角即可分享
微信分享提示
CONTENTS