如何配置Kestrel以使用随机动态端口并在运行时使用ASP.NET Core 3.1确定端口?

借助ASP.NET Core 3.0,我已经能够使用此IHostedService方法...

Determine port Kestrel binded to

...在运行时确定Kestrel的动态端口。

IServerAddressesFeature在此处记录了ASP.NET 3.0:

https://docs.microsoft.com/en-us/dotnet/api/microsoft.aspnetcore.hosting.server.features.iserveraddressesfeature?view=aspnetcore-3.0

但是,当将版本更改为ASP.NET Core 3.1时,页面将重定向回ASP.NET 3.0,并提示该文档不适用于ASP.NET Core 3.1。 IServerAddressesFeature不再工作了吗?将IServerAddressesFeature与ASP.NET Core 3.1一起使用仍然可以编译,但是返回的ServerAddresses中的端口始终为零。

程序:

public class Program
{
    public static void Main(string[] args)
    {
        BuildWebHost().Run();
    }

    public static IWebHost BuildWebHost() =>

        WebHost.CreateDefaultBuilder()
            .UseKestrel()
            .UseUrls("http://127.0.0.1:0") // port zero to use random dynamic port
            .UseStartup<Startup>()
            .Build();
}

稍后,当调用Configure时...

    public void Configure(IApplicationBuilder app,IWebHostEnvironment env)
    {
        HostedService.ServerAddresses = app.ServerFeatures.Get<microsoft.AspNetCore.Hosting.Server.Features.IServerAddressesFeature>();

...如链接示例中所示,服务器地址已分配给HostedService.ServerAddresses静态变量。但是,ServerAddresses仅包含端口为零的环回地址:"http://127.0.0.1:0"

我在俯视什么吗? v3.1中是否有其他适当的方法来解决此问题?如何使用ASP.NET Core 3.1将Kestrel配置为使用随机动态端口并确定运行时该端口位于哪个端口(在执行任何控制器操作之前)?

更新

这是一个丑陋的解决方法,可帮助您确定端口。动态端口分配的时间或顺序似乎已更改。从HostedService.StartAsync方法返回并稍后读取服务器地址似乎就足够了。当然必须有更好的方法吗?

        public Task StartAsync(CancellationToken cancellationToken)
        {
            System.Threading.Tasks.Task.Run(async () =>
            {
                int port = 0;
                while (port == 0)
                {
                    // a single delay seems to be sufficient
                    await System.Threading.Tasks.Task.Delay(100);
                    var address = ServerAddresses.Addresses.Single();
                    // address in this app is always in form http://127.0.0.1:port
                    var pos = address.LastIndexOf(':');
                    var portString = address.Substring(pos + 1);
                    port = int.Parse(portString);
                }
                // have determined the dynamic port now
            });
            return System.Threading.Tasks.Task.CompletedTask;
        }
nbayjj 回答:如何配置Kestrel以使用随机动态端口并在运行时使用ASP.NET Core 3.1确定端口?

IHostedService方法不起作用的原因是因为执行IHostedServices时.Net Core 3发生了更改。在.Net Core 2中,主机启动后执行了IHostedService,因此可以轻松获得服务器地址信息。在.Net Core 3中,IHostedService在构建主机之后但在主机启动之前运行,并且该地址尚不可用。 This blog很好地解释了变化。

here复制的以下获取绑定地址的方法适用于.Net Core 2和3。

您可以呼叫IWebHost.Start()而不是按照建议的here呼叫IWebHost.Run()。这将允许继续执行Main方法,以便您可以从IWebHost.ServerFeatures获取所需的信息。请记住,您的应用程序将立即关闭,除非您明确告知不要使用IWebHost.WaitForShutdown()

 public static void Main(string[] args)
    {
        var host = new WebHostBuilder()
            .UseStartup<Startup>()
            .UseUrls("http://*:0") // This enables binding to random port
            .Build();

        host.Start();

        foreach(var address in host.ServerFeatures.Get<IServerAddressesFeature>().Addresses)
        {
            var uri = new Uri(address);
            var port = uri.Port;

            Console.WriteLine($"Bound to port: {port}");
        }

        //Tell the host to block the thread just as host.Run() would have.
        host.WaitForShutdown();
    }
本文链接:https://www.f2er.com/2962757.html

大家都在问