Evolution and Improvement of Overall Concepts
- ASP. NET Core Overall Conceptual Deduction
- Deduce the whole concept to a specific form
ASP. NET Core Overall Conceptual Deduction
ASP. NET Core essentially handles HTTP requests and provides HTTP responses through the web framework
The web framework is used by programmers and includes ASP. NET Core, Express, spring, etc.
So we're done with ASP. NET Core's underlying modeling, followed by refinement of HTTP requests and HTTP responses
For raw HTTP requests, the server listens on the IP port through the listening configuration
An IP port connects to a Socket network, which is divided into input stream and output stream
input stream receives and transforms HTTP request connections (C#identifiable), including HTTPContext
Generate output stream after HTTP request connection is processed
Deduce the whole concept to a specific form
Endpoint has an Options configuration for configuring Socket s
TransportFactory is divided into SocketTransportFactory and LiburyTransportFactory
TransportFactory binds ConnectionListener, which listens for Socket requests
Create SocketConnection based on Socket to form ConnectionContext
After creation, through the Start method, start receiving send requests, corresponding to the output stream of the Socket network connection, to the process before processing
Next, find the above process from the source code: https://github.com/dotnet/aspnetcore/
There is a WebHostBuilderKestrelExtensions extension method injected into KestrelServerImpl in the src/Servers/Kestrel/Kestrel directory
services.AddSingleton<IServer, KestrelServerImpl>();
KestrelServerImpl is an interface inherited from IServer, IServer is in Hosting, and IServer has a StartAsync method
Task StartAsync<TContext>(IHttpApplication<TContext> application, CancellationToken cancellationToken) where TContext : notnull;
We can find a OnBind method in KestrelServerImpl's StartAsync method
async Task OnBind(ListenOptions options, CancellationToken onBindCancellationToken)
In this OnBind method you can see that the entire options are in ListenOptions, and the EndPoint property is in ListenOptions
public EndPoint EndPoint { get; internal set; }
Listening is actually broken down into several methods, starting with a binding method that passes an EndPoint to the TransportManager binding method
options.EndPoint = await _transportManager.BindAsync(options.EndPoint, multiplexedConnectionDelegate, options, onBindCancellationToken).ConfigureAwait(false);
TransportManager's binding method uses TransportFactory's binding method
var transport = await _multiplexedTransportFactory.BindAsync(endPoint, features, cancellationToken).ConfigureAwait(false);
TransportFactory is an IConnectionListenerFactory that has two implementations: SocketTransportFactory, LiburyTransportFactory
A listener for the SocketConnectionListener is generated in the binding method of the SocketTransportFactory
var transport = new SocketConnectionListener(endpoint, _options, _logger);
SocketConnectionListener is generated by SocketConnectionListenerFactory, which inherits from IConConnectionListenerFactory
After creating the SocketConnectionListener listener, call the StartAcceptLoop method to pass in the connectionListener
StartAcceptLoop(new GenericConnectionListener(transport), c => connectionDelegate(c), endpointConfig);
Start receiving in the StartAcceptLoop method
var acceptLoopTask = connectionDispatcher.StartAcceptingConnections(connectionListener);
Receive AceptAsync method that calls listener in StartAcceptingConnections
var connection = await listener.AcceptAsync();
SocketConnectionListener's AceptAsync method produces a ConnectionContext
public ValueTask<ConnectionContext?> AcceptAsync(CancellationToken cancellationToken = default)
This ConnectionContext was created by SocketConnectionContextFactory
return _factory.Create(acceptSocket);
The Create method creates a SocketConnection with InputOptions and OutputOptions
var connection = new SocketConnection(socket, _memoryPool, setting.Scheduler, _logger, setting.SocketSenderPool, setting.InputOptions, setting.OutputOptions, waitForData: _options.WaitForDataBeforeAllocatingBuffer);
Start directly after creation, this is a self-starting process
connection.Start();
Create a KestrelConnection after the StartAcceptingConnections get a SocketConnection, which is transformed by _ ConneionDelegate execution
var kestrelConnection = new KestrelConnection<T>( id, _serviceContext, _transportConnectionManager, _connectionDelegate, connection, Log);
In ExecuteAsync, the execution method of KestrelConnection, calls _ ConneionDelegate
await _connectionDelegate(connectionContext);
Next, leave it all to HttpConnectionMiddleware to see how to build and create in KestrelServerImpl
options.UseHttpServer(ServiceContext, application, options.Protocols, addAltSvcHeader); var connectionDelegate = options.Build();
Create HttpConnectionMiddleware in UseHttpServer
var middleware = new HttpConnectionMiddleware<TContext>(serviceContext, application, protocols, addAltSvcHeader);
Open execution of HttpConnectionContext in HttpConnectionMiddleware
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);
Start the ontext conversion protocol for requestProcessor in ProcessRequestsAsync
public async Task ProcessRequestsAsync<TContext>(IHttpApplication<TContext> httpApplication) where TContext : notnull
task
After understanding asp. After the architecture of layer 2 of net core, starting with HttpConnectionMiddleware, the conversion of KestrelConnection to HttpContext is refined with OPD