Aspnetcore.docs: Update Kestrel doc for 3.0 (Generic Host)

Created on 12 Jun 2019  Â·  6Comments  Â·  Source: dotnet/AspNetCore.Docs


Document Details

⚠ Do not edit this section. It is required for docs.microsoft.com ➟ GitHub issue linking.

P1

Most helpful comment

I have confirmed that the ListenHandle requires libuv support, which can be added through approaches in https://docs.microsoft.com/en-us/aspnet/core/fundamentals/servers/kestrel?view=aspnetcore-3.0#transport-configuration. I suggest a clearer description of ListenHandle illustrating the requirement on libuv.

The working code is:

using System;
using Microsoft.AspNetCore;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Hosting;

namespace KestrelSample
{
    public class Program
    {
        public static void Main(string[] args)
        {
            CreateHostBuilder(args).Build().Run();
        }

        public static IWebHostBuilder CreateHostBuilder(string[] args) =>
            WebHost.CreateDefaultBuilder(args)
                .UseLibuv()
                .ConfigureKestrel(serverOptions =>
                {
                    var fds = Environment.GetEnvironmentVariable("LISTEN_FDS");
                    var fd = ulong.Parse(fds);

                    serverOptions.ListenHandle(3);
                })
                .UseStartup<Startup>();
    }
}

All 6 comments

cc: @coderfox

@halter73 Two questions ...

FileDescriptor

For our Kestrel FileDescriptor example in the sample app with the 3.0 updates ...

using System;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Hosting;

namespace KestrelSample
{
    public class Program
    {
        public static void Main(string[] args)
        {
            CreateHostBuilder(args).Build().Run();
        }

        public static IHostBuilder CreateHostBuilder(string[] args) =>
            Host.CreateDefaultBuilder(args)
                .ConfigureWebHostDefaults(webBuilder =>
                {
                    webBuilder.ConfigureKestrel(serverOptions =>
                    {
                        var fds = Environment
                            .GetEnvironmentVariable("SD_LISTEN_FDS_START");
                        var fd = ulong.Parse(fds);

                        serverOptions.ListenHandle(fd);
                        serverOptions.ListenHandle(fd, listenOptions =>
                        {
                            listenOptions.UseHttps("testCert.pfx", "testpassword");
                        });
                    })
                    .UseStartup<Startup>();
                });
    }
}

... it's throwing ...

crit: Microsoft.AspNetCore.Server.Kestrel[0]
      Unable to start Kestrel.
System.NotImplementedException: This property is not implemented by this class.
   at System.Net.EndPoint.get_AddressFamily()
   at Microsoft.AspNetCore.Server.Kestrel.Transport.Sockets.SocketConnectionListener.Bind()
   at Microsoft.AspNetCore.Server.Kestrel.Transport.Sockets.SocketTransportFactory.BindAsync(EndPoint endpoint, CancellationToken cancellationToken)
   at Microsoft.AspNetCore.Server.Kestrel.Core.KestrelServer.<>c__DisplayClass21_0`1.<<StartAsync>g__OnBind|0>d.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.AddressBinder.BindEndpointAsync(ListenOptions endpoint, AddressBindContext context)
   at Microsoft.AspNetCore.Server.Kestrel.Core.ListenOptions.BindAsync(AddressBindContext context)
   at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.AddressBinder.EndpointsStrategy.BindAsync(AddressBindContext context)
   at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.AddressBinder.BindAsync(IServerAddressesFeature addresses, KestrelServerOptions serverOptions, ILogger logger, Func`2 createBinding)
   at Microsoft.AspNetCore.Server.Kestrel.Core.KestrelServer.StartAsync[TContext](IHttpApplication`1 application, CancellationToken cancellationToken)
Unhandled exception. System.NotImplementedException: This property is not implemented by this class.
   at System.Net.EndPoint.get_AddressFamily()
   at Microsoft.AspNetCore.Server.Kestrel.Transport.Sockets.SocketConnectionListener.Bind()
   at Microsoft.AspNetCore.Server.Kestrel.Transport.Sockets.SocketTransportFactory.BindAsync(EndPoint endpoint, CancellationToken cancellationToken)
   at Microsoft.AspNetCore.Server.Kestrel.Core.KestrelServer.<>c__DisplayClass21_0`1.<<StartAsync>g__OnBind|0>d.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.AddressBinder.BindEndpointAsync(ListenOptions endpoint, AddressBindContext context)
   at Microsoft.AspNetCore.Server.Kestrel.Core.ListenOptions.BindAsync(AddressBindContext context)
   at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.AddressBinder.EndpointsStrategy.BindAsync(AddressBindContext context)
   at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.AddressBinder.BindAsync(IServerAddressesFeature addresses, KestrelServerOptions serverOptions, ILogger logger, Func`2 createBinding)
   at Microsoft.AspNetCore.Server.Kestrel.Core.KestrelServer.StartAsync[TContext](IHttpApplication`1 application, CancellationToken cancellationToken)
   at Microsoft.AspNetCore.Hosting.WebHost.StartAsync(CancellationToken cancellationToken)
   at Microsoft.AspNetCore.Hosting.WebHostExtensions.RunAsync(IWebHost host, CancellationToken token, String startupMessage)
   at Microsoft.AspNetCore.Hosting.WebHostExtensions.RunAsync(IWebHost host, CancellationToken token, String startupMessage)
   at Microsoft.AspNetCore.Hosting.WebHostExtensions.RunAsync(IWebHost host, CancellationToken token)
   at Microsoft.AspNetCore.Hosting.WebHostExtensions.Run(IWebHost host)
   at KestrelSample.Program.Main(String[] args) in /AspNetCore.Docs/aspnetcore/fundamentals/servers/kestrel/samples/2.x/KestrelSample/Program.cs:line 74

Do you have any tips on getting it running?

serverOptions.Configure

I can't see in engineering repo code where/how to get a context for serverOptions.Configure. Under 3.0 and looking at ...

https://github.com/aspnet/AspNetCore/blob/master/src/Servers/Kestrel/samples/SampleApp/Startup.cs#L78

... it looks like the code supposed to use UseKestrel to pass an IConfiguration ...

public static IHostBuilder CreateHostBuilder(string[] args) =>
    Host.CreateDefaultBuilder(args)
        .ConfigureWebHostDefaults(webBuilder =>
        {
            //
            // LIKE THIS ...............
            //
            webBuilder.UseKestrel((context, options) =>
            {
                options.Configure(context.Configuration.GetSection("{SECTION}"));
            })
            .ConfigureKestrel(serverOptions =>
            {
                //
                // OR ... Is there a way to get an IConfiguration in here?
                //
                serverOptions.Configure( ... ? ...)
                serverOptions.Listen(IPAddress.Loopback, 5000);
                serverOptions.Listen(IPAddress.Loopback, 5001, 
                    listenOptions =>
                    {
                        listenOptions.UseHttps("testCert.pfx", 
                            "testPassword");
                    });
            })
            .UseStartup<Startup>();
        });

I have confirmed that the ListenHandle requires libuv support, which can be added through approaches in https://docs.microsoft.com/en-us/aspnet/core/fundamentals/servers/kestrel?view=aspnetcore-3.0#transport-configuration. I suggest a clearer description of ListenHandle illustrating the requirement on libuv.

The working code is:

using System;
using Microsoft.AspNetCore;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Hosting;

namespace KestrelSample
{
    public class Program
    {
        public static void Main(string[] args)
        {
            CreateHostBuilder(args).Build().Run();
        }

        public static IWebHostBuilder CreateHostBuilder(string[] args) =>
            WebHost.CreateDefaultBuilder(args)
                .UseLibuv()
                .ConfigureKestrel(serverOptions =>
                {
                    var fds = Environment.GetEnvironmentVariable("LISTEN_FDS");
                    var fd = ulong.Parse(fds);

                    serverOptions.ListenHandle(3);
                })
                .UseStartup<Startup>();
    }
}

Thanks @coderfox ... I'm working on the Kestrel updates for 3.0 now, and I'll roll updates on the PR.

Looking at https://www.freedesktop.org/software/systemd/man/sd_listen_fds.html ...

Doesn't SD_LISTEN_FDS_START resolve to 3, thus can you put fd back into ListenHandle there?

@guardrex In my scenario, I am using systemfd for holding sockets in debugging, and there is not such SD_LISTEN_FDS_START so I have to hard code it, but for normal situations, SD_LISTEN_FDS_START may be used as fd.

@guardrex, @coderfox is correct that the libuv transport is required for ListenHandle to work. I have a PR open to provide a good exception message in this case: https://github.com/aspnet/AspNetCore/pull/13079

Thx @halter73 ... I already added it to the Kestrel PR, but I'll hold off on calling for your review until later in the week.

Was this page helpful?
0 / 5 - 0 ratings