. NET Core Development logs-from the ASP.

Source: Internet
Author: User
Tags hosting webhost

The ASP. NET Core program now becomes the same as the console program, which also launches the entire application through the main method. The main method to do is simple, create a Webhostbuilder class, call its build method to generate a webhost class, and finally start it.

Implementation code at a glance:

public class Program{    public static void Main(string[] args)    {        CreateWebHostBuilder(args).Build().Run();    }    public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>        WebHost.CreateDefaultBuilder(args)            .UseStartup<Startup>();}

To find out what is going on inside, you need to investigate the Createdefaultbuilder static method in the Webhost class:

public static Iwebhostbuilder Createdefaultbuilder (string[] args) {var builder = new Webhostbuilder (); if (string. IsNullOrEmpty (builder. GetSetting (Webhostdefaults.contentrootkey)) {Builder.    Usecontentroot (Directory.GetCurrentDirectory ()); } if (args! = null) {Builder. Useconfiguration (New Configurationbuilder (). Addcommandline (args).    Build ()); } builder. Usekestrel (buildercontext, options) = {options.        Configure (BuilderContext.Configuration.GetSection ("Kestrel")); })        .            Configureappconfiguration ((hostingcontext, config) = = {var env = hostingcontext.hostingenvironment; Config. Addjsonfile ("Appsettings.json", Optional:true, Reloadonchange:true). Addjsonfile ($ "appsettings.{ Env.            Environmentname}.json ", Optional:true, Reloadonchange:true); if (env. Isdevelopment ()) {var appassembly = Assembly.Load (New AssemblyName (env). ApplicationName)); if (appassembly! = null) {config.                Addusersecrets (appassembly, optional:true); }} config.            Addenvironmentvariables (); if (args! = null) {config.            Addcommandline (args); }        })        . Configurelogging (hostingcontext, logging) = {logging.            Addconfiguration (HostingContext.Configuration.GetSection ("Logging")); Logging.            Addconsole (); Logging.        Adddebug (); })        . Configureservices (hostingcontext, services) = {//Fallback services. postconfigure

The code is a little bit more, but it only cares about the creation of the Webhostbuilder class, and the builder uses the Usekestrel method.

The Usekestrel method injects the Kestrelserver class within the IOC way:

public static IWebHostBuilder UseKestrel(this IWebHostBuilder hostBuilder){ return hostBuilder.ConfigureServices(services => { // Don‘t override an already-configured transport services.TryAddSingleton<ITransportFactory, SocketTransportFactory>(); services.AddTransient<IConfigureOptions<KestrelServerOptions>, KestrelServerOptionsSetup>(); services.AddSingleton<IServer, KestrelServer>(); });}

This lets you know that when an ASP. NET core application is running, it will have kestrelserver inside.

So why do you need this kestrelserver? Because it can be used as a reverse proxy server, it helps ASP. NET core to achieve cross-platform needs.

In the case of IIS on a traditional Windows system, as shown in, the code in the ASP. NET core application is no longer directly dependent on the IIS container, but instead transforms the HTTP request into a HttpContext object by Kestrelserver the proxy. This object is then processed.

The ASP. NET core module in the diagram is also a new IIS module introduced by the birth of ASP. Its primary function is to redirect Web requests to an ASP. NET Core application. And because the ASP. NET core application runs independently of processes outside the IIS worker process, it is also responsible for managing the process.

The source code for the ASP. NET Core module is written in C + +, which is the Registermodule function in the main file.

Its function internally instantiates the Cproxymodulefactory factory class.

pFactory = new CProxyModuleFactory;

There is a key Cproxymodule::onexecuterequesthandler method in the Cproxymodule instance created by this factory class. It creates a Forwarding_handler instance and calls its Onexecuterequesthandler method.

__overrideREQUEST_NOTIFICATION_STATUSCProxyModule::OnExecuteRequestHandler( IHttpContext * pHttpContext, IHttpEventProvider *){ m_pHandler = new FORWARDING_HANDLER(pHttpContext); if (m_pHandler == NULL) { pHttpContext->GetResponse()->SetStatus(500, "Internal Server Error", 0, E_OUTOFMEMORY); return RQ_NOTIFICATION_FINISH_REQUEST; } return m_pHandler->OnExecuteRequestHandler();}

In this method, there are the core operations that handle HTTP requests.

// 实例化应用程序管理器pApplicationManager = APPLICATION_MANAGER::GetInstance();// 取得应用程序实例hr = pApplicationManager->GetApplication(m_pW3Context, &m_pApplication);// 取得该应用程序的进程hr = m_pApplication->GetProcess(m_pW3Context, pAspNetCoreConfig, &pServerProcess);// 创建HTTP请求hr = CreateWinHttpRequest(pRequest, pProtocol, hConnect, &struEscapedUrl, pAspNetCoreConfig, pServerProcess);// 发送HTTP请求if (!WinHttpSendRequest(m_hRequest, m_pszHeaders, m_cchHeaders, NULL, 0, cbContentLength, reinterpret_cast<DWORD_PTR>(static_cast<PVOID>(this)))){ hr = HRESULT_FROM_WIN32(GetLastError()); DebugPrintf(ASPNETCORE_DEBUG_FLAG_INFO, "FORWARDING_HANDLER::OnExecuteRequestHandler, Send request failed"); goto Failure;}

At the end of the ASP. NET core application, CreateWebHostBuilder(args).Build().Run(); after the code executes, its corresponding Async method is called:

private static Async Task RunAsync (this iwebhost host, CancellationToken token, string shutdownmessage) {using (host) {await host.} Startasync (token); var hostingenvironment = host. Services.getservice<ihostingenvironment> (); var options = host. Services.getrequiredservice<webhostoptions> (); if (!options. Suppressstatusmessages) {Console.WriteLine ($ "Hosting environment: {hostingenvironment.environmentname}" ); Console.WriteLine ($ "Content root path: {hostingenvironment.contentrootpath}"); var serveraddresses = host. Serverfeatures.get<iserveraddressesfeature> ()?. Addresses; if (serveraddresses! = null) {foreach (var address in serveraddresses) { Console.WriteLine ($ "Now listening on: {address}"); }} if (!string. IsNullOrEmpty (Shutdownmessage)) {Console.WriteLine (ShutdowNmessage); }} await host. Waitfortokenshutdownasync (token); }}

This method also calls the Startasync method for webhost:

Public virtual Async Task Startasync (cancellationtoken cancellationtoken = default) {HostingEventSource.Log.HostStart (    );    _logger = _applicationservices.getrequiredservice<ilogger<webhost>> (); _logger.    Starting ();    var application = Buildapplication (); _applicationlifetime = _applicationservices.getrequiredservice<iapplicationlifetime> () as    Applicationlifetime;    _hostedserviceexecutor = _applicationservices.getrequiredservice

The Buildapplication method internally extracts an instance of Kestrelserver from the IOC container:

private void EnsureServer(){ if (Server == null) { Server = _applicationServices.GetRequiredService<IServer>(); var serverAddressesFeature = Server.Features?.Get<IServerAddressesFeature>(); var addresses = serverAddressesFeature?.Addresses; if (addresses != null && !addresses.IsReadOnly && addresses.Count == 0) { var urls = _config[WebHostDefaults.ServerUrlsKey] ?? _config[DeprecatedServerUrlsKey]; if (!string.IsNullOrEmpty(urls)) { serverAddressesFeature.PreferHostingUrls = WebHostUtilities.ParseBool(_config, WebHostDefaults.PreferHostingUrlsKey); foreach (var value in urls.Split(new[] { ‘;‘ }, StringSplitOptions.RemoveEmptyEntries)) { addresses.Add(value); } } } }}

The Startasync method that last called Kestrelserver:

Public async Task startasync<tcontext> (ihttpapplication<tcontext> application, CancellationToken CancellationToken) {try {if (! Bitconverter.islittleendian) {throw new PlatformNotSupportedException (corestrings.bigendiannotsupported        );        } validateoptions ();  if (_hasstarted) {//The server has already started and/or have not been cleaned up yet throw        New InvalidOperationException (corestrings.serveralreadystarted);        } _hasstarted = true; _heartbeat.        Start (); Async Task Onbind (listenoptions endpoint) {//ADD the HTTP middleware as the terminal connection middle Ware endpoint. Usehttpserver (endpoint. Connectionadapters, Servicecontext, application, endpoint.            protocols); var connectiondelegate = endpoint.            Build (); Add the connection limit middleware if (Options.Limits.MaxConcurrentConnections.HasValue) {               Connectiondelegate = new Connectionlimitmiddleware (connectiondelegate, Options.Limits.MaxConcurrentConnecti Ons. Value, Trace).            Onconnectionasync;            } var connectiondispatcher = new Connectiondispatcher (Servicecontext, connectiondelegate);            var transport = _transportfactory.create (endpoint, connectiondispatcher); _transports.            ADD (transport); Await transport. Bindasync ().        Configureawait (FALSE); } await Addressbinder.bindasync (_serveraddresses, Options, Trace, Onbind).    Configureawait (FALSE);        } catch (Exception ex) {trace.logcritical (0, ex, "unable to start Kestrel.");        Dispose ();    Throw }}

At this point, kestrelserver can finally listen for HTTP requests from the ASP. NET core application can also start its own task processing.

. NET Core Development logs-from the ASP.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.