确定端口Kestrel绑定到 [英] Determine port Kestrel binded to

查看:91
本文介绍了确定端口Kestrel绑定到的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用ASP.NET Core空(web)模板编写一个简单的ASP.NET Core服务.

I'm writing a simple ASP.NET Core service using ASP.NET Core empty (web) template.

默认情况下,它绑定到端口5000,但我希望它绑定到系统上的随机可用端口.

By default, it binds to port 5000 but I would like it to bind to a random available port on the system.

我可以通过将BuildWebHost修改为:

    public static IWebHost BuildWebHost(string[] args) =>
        WebHost.CreateDefaultBuilder(args)
            .UseStartup<Startup>()
            .UseUrls("http://*:0") // This enables binding to random port
            .Build();

它绑定到随机端口,但是如何从应用程序中确定我正在侦听哪个端口?

It binds to a random port but how do I determine from within the application which port I'm listening to?

推荐答案

可以通过IServerAddressesFeature.Addresses集合访问ASP.NET Core应用程序的托管地址.

Hosting addresses of ASP.NET Core application could be accessed via IServerAddressesFeature.Addresses collection.

主要挑战是调用代码,该代码将在正确的时间分析此集合.实际的端口绑定发生在调用IWebHost.Run()时(从Program.Main()开始).因此,您尚不能使用Startup.Configure()方法访问托管地址,因为在此阶段尚未分配端口.调用IWebHost.Run()后,您将失去控制,因为直到Web主机关闭,该调用才会返回.

The main challenge is to invoke the code, which will analyze this collection, at the right time. The actual port binding happens when IWebHost.Run() is called (from Program.Main()). Therefore you can't yet access hosting address in Startup.Configure() method, because port has not been yet assigned on this stage. And you loose control after calling IWebHost.Run(), because this call does not return untill web host is shut down.

据我了解,分析绑定端口的最合适方法是通过实现

In my understanding, the most suitable way to analyze bound port is through implementation of IHostedService. Here is working sample:

public class GetBindingHostedService : IHostedService
{
    public static IServerAddressesFeature ServerAddresses { get; set; }

    public Task StartAsync(CancellationToken cancellationToken)
    {
        var address = ServerAddresses.Addresses.Single();
        var match = Regex.Match(address, @"^.+:(\d+)$");
        if (match.Success)
        {
            int port = Int32.Parse(match.Groups[1].Value);
            Console.WriteLine($"Bound port is {port}");
        }

        return Task.CompletedTask;
    }

    public Task StopAsync(CancellationToken cancellationToken)
    {
        return Task.CompletedTask;
    }
}

Startup类中:

public class Startup
{

    //  ...

    public void ConfigureServices(IServiceCollection services)
    {
        services.AddMvc();
        services.AddSingleton<IHostedService, GetBindingHostedService>();
    }

    public void Configure(IApplicationBuilder app, IHostingEnvironment env)
    {
        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
        }

        app.UseMvc();

        GetBindingHostedService.ServerAddresses = app.ServerFeatures.Get<IServerAddressesFeature>();
    }
}

IServerAddressesFeature的实例通过GetBindingHostedService中的丑陋静态属性传递.我看不到如何将其注入服务中.

Instance of IServerAddressesFeature is passed through ugly static property in GetBindingHostedService. I don't see other way how it could be injected into the service.

GitHub上的示例项目

总的来说,我对这种解决方案不满意.它可以完成工作,但是看起来比它应该的要复杂得多.

Overall I'm not happy with such solution. It does the job, however it seems much more complex than it should be.

这篇关于确定端口Kestrel绑定到的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆