• 为什么推荐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,大家慢慢品吧。

    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("/mqtt"); // SingalR over Websocket app.MapHub("/signalr");

    4.3 自定义应用层#

    我们这里说所的应用层协议,往往是我们在这层协议上构建了业务,而不拿它来做传输协议,而实际中,一种协议往往即可以做广义的传输协议,也可以直接做构建业务的应用层协议(典型的WebSocket,甚至http也可以做传输协议)。在asp.netcore中,SingalR就是典型的一个不太复杂的应用层协议(相对http),我们也可以基于kestrel来开发telnet over tcp的服务,telnet做为应用层,tcp做传输层。

    Copy
    public class TelnetConnectionHandler : ConnectionHandler { /// /// 收到Telnet连接后 /// /// /// public override async Task OnConnectedAsync(ConnectionContext connection) { var input = connection.Transport.Input; var output = connection.Transport.Output; // 从input解析telnet协议 ... } }
    Copy
    public static class ListenOptionsExtensions { /// /// 使用TelnetConnectionHandler /// /// public static void UseTelnet(this ListenOptions listen) { listen.UseConnectionHandler(); } }
    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

  • 相关阅读:
    适合能源企业的文档安全外发系统应该是什么样的?
    python 基本概念整理
    为什么你开发的网页不应该大于 14KB?你知道原理吗
    Image,cv2读取图片的numpy数组的转换和尺寸resize变化
    【TypeScript】中的函数详解
    JMeter接口测试工具基础— 取样器sampler(二)
    还在纠结笔记工具的选择么? 各种笔记工具帮你总结了
    Springboot毕业设计毕设作品,汽车租赁管理系统设计与实现
    毫米波点云雷达 论文阅读 | 3DRIMR, IPCCC 2021
    问一下ChatGPT如何学习开发iOS应用程序
  • 原文地址:https://www.cnblogs.com/kewei/p/16955086.html