.NET 云原生架构师训练营(ASP .NET Core 整体概念推演)--学习笔记
演化与完善整体概念
- ASP .NET Core 整体概念推演
- 整体概念推演到具体的形式
ASP .NET Core 整体概念推演
ASP .NET Core 其实就是通过 web framework 处理 HTTP 请求并提供 HTTP 响应
web framework 由程序员使用,它包括 ASP .NET Core,Express,spring 等等组成
这样我们就完成了对 ASP .NET Core 的底层建模,接下来对 HTTP 请求和 HTTP 响应进行细化
对于原始 HTTP 请求,服务器通过监听配置对 IP 端口进行监听
IP 端口与 Socket 网络建立连接,Socket 网络连接分为 input stream 和 output stream
input stream 接收并转化 HTTP 请求连接(C# 可识别),包括 HTTPContext
HTTP 请求连接经过处理之后生成 output stream
整体概念推演到具体的形式
Endpoint 有一个 Options 配置,用于配置 Socket
TransportFactory 分为 SocketTransportFactory 和 LiburyTransportFactory
TransportFactory 绑定 ConnectionListener,ConnectionListener 监听 Socket 请求
基于 Socket 创建 SocketConnection,组成 ConnectionContext
创建之后通过 Start 方法,开始接收发送请求,对应 Socket 网络连接的 output stream 到处理之前的过程
接下来通过源码找到上述的过程:https://github.com/dotnet/aspnetcore/
在 src/Servers/Kestrel/Kestrel 目录下有一个 WebHostBuilderKestrelExtensions 的扩展方法注入了 KestrelServerImpl
services.AddSingleton<IServer, KestrelServerImpl>();
KestrelServerImpl 是继承自 IServer 的接口,IServer 是在 Hosting 中的,在 IServer 中有一个 StartAsync 的方法
Task StartAsync<TContext>(IHttpApplication<TContext> application, CancellationToken cancellationToken) where TContext : notnull;
在 KestrelServerImpl 的 StartAsync 方法中我们可以找到一个 OnBind 的方法
async Task OnBind(ListenOptions options, CancellationToken onBindCancellationToken)
在这个 OnBind 方法中可以看到整个 options 在 ListenOptions 里面,而在 ListenOptions 里面可以看到 EndPoint 属性
public EndPoint EndPoint { get; internal set; }
监听实际上会被拆解成好几个方法,首先是一个绑定的方法,把 EndPoint 传入到 TransportManager 的绑定方法
options.EndPoint = await _transportManager.BindAsync(options.EndPoint, multiplexedConnectionDelegate, options, onBindCancellationToken).ConfigureAwait(false);
TransportManager 的绑定方法使用了 TransportFactory 的绑定方法
var transport = await _multiplexedTransportFactory.BindAsync(endPoint, features, cancellationToken).ConfigureAwait(false);
TransportFactory 是一个 IConnectionListenerFactory,它有两个实现:SocketTransportFactory,LiburyTransportFactory
在 SocketTransportFactory 的绑定方法中会产生一个 SocketConnectionListener 的监听器
var transport = new SocketConnectionListener(endpoint, _options, _logger);
SocketConnectionListener 是由 SocketConnectionListenerFactory 产生的,SocketConnectionListenerFactory 继承自 IConnectionListenerFactory
创建 SocketConnectionListener 监听器之后调用 StartAcceptLoop 方法传入 connectionListener
StartAcceptLoop(new GenericConnectionListener(transport), c => connectionDelegate(c), endpointConfig);
在 StartAcceptLoop 方法中开始接收
var acceptLoopTask = connectionDispatcher.StartAcceptingConnections(connectionListener);
在 StartAcceptingConnections 中调用了 listener 的 AcceptAsync 方法接收
var connection = await listener.AcceptAsync();
SocketConnectionListener 的 AcceptAsync 方法会产生一个 ConnectionContext
public ValueTask<ConnectionContext?> AcceptAsync(CancellationToken cancellationToken = default)
这个 ConnectionContext 由 SocketConnectionContextFactory 创建
return _factory.Create(acceptSocket);
Create 方法创建了一个 SocketConnection,这个连接里面有 InputOptions 和 OutputOptions
var connection = new SocketConnection(socket,
_memoryPool,
setting.Scheduler,
_logger,
setting.SocketSenderPool,
setting.InputOptions,
setting.OutputOptions,
waitForData: _options.WaitForDataBeforeAllocatingBuffer);
创建之后直接启动,这是一个自启动的过程
connection.Start();
在 StartAcceptingConnections 得到 SocketConnection 后创建 KestrelConnection,创建之后的转化由 _connectionDelegate 执行
var kestrelConnection = new KestrelConnection<T>(
id, _serviceContext, _transportConnectionManager, _connectionDelegate, connection, Log);
在 KestrelConnection 的执行方法 ExecuteAsync 里面,调用了 _connectionDelegate
await _connectionDelegate(connectionContext);
接下来全部交给 HttpConnectionMiddleware 处理,看一下如何在 KestrelServerImpl 中构建创建
options.UseHttpServer(ServiceContext, application, options.Protocols, addAltSvcHeader);
var connectionDelegate = options.Build();
在 UseHttpServer 中创建 HttpConnectionMiddleware
var middleware = new HttpConnectionMiddleware<TContext>(serviceContext, application, protocols, addAltSvcHeader);
在 HttpConnectionMiddleware 中开启 HttpConnectionContext 的执行
var httpConnectionContext = new HttpConnectionContext(
connectionContext.ConnectionId,
protocols,
altSvcHeader,
connectionContext,
_serviceContext,
connectionContext.Features,
memoryPoolFeature?.MemoryPool ?? System.Buffers.MemoryPool<byte>.Shared,
localEndPoint,
connectionContext.RemoteEndPoint as IPEndPoint);
httpConnectionContext.Transport = connectionContext.Transport;
var connection = new HttpConnection(httpConnectionContext);
return connection.ProcessRequestsAsync(_application);
在 ProcessRequestsAsync 中开始 requestProcessor 的 Context 的转化协议
public async Task ProcessRequestsAsync<TContext>(IHttpApplication<TContext> httpApplication) where TContext : notnull
作业
在了解完 asp .net core 第2层的架构之后, 从 HttpConnectionMiddleware 开始,把 KestrelConnection 到 HttpContext 的转化过程用OPD 进行细化
相关文章
- WPF开发入门尝试
- 微软公告:ASP.NET曝漏洞 Win7等均中招
- WCF初接触实作之服务发布和使用
- WCF初次操作实践
- .NET程序员快来Visual Studio刷“成就”
- .NET垃圾回收机制知识点整理
- ASP.NET_正则表达式_匹配HTML中的一行或多行
- 利用WCF实现将服务器端的错误信息返回
- 怎样做一个快乐的ASP.NET程序员
- 为什么我们不要.NET程序员
- DDD落地,如何持久化聚合
- 迁移 dotnet 6 提示必须将目标平台设置为 Windows 平台
- C++|I/O|基于缓冲区的位级IO流
- 006: Django ajax请求
- 012:Django高级请求
- 开发者调查:C#在云应用中失去了地位 在游戏中依然大行其道
- 彻底理解 IO 多路复用实现机制
- 微软.NET 5.1迎来RC1版本 开发者已可上线尝鲜
- 速度和性能狂卷,.NET 7有多少人买单
- 风云再续:他抖任他抖,IO诊断在我手