Asp.net-Core

確定 Kestrel 綁定到的埠

  • March 21, 2020

我正在使用 ASP.NET Core 空 ( web) 模板編寫一個簡單的 ASP.NET Core 服務。

預設情況下,它綁定到埠 5000,但我希望它綁定到系統上的隨機可用埠。

我可以通過修改來做到這一點BuildWebHost

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

它綁定到一個隨機埠,但我如何從應用程序中確定我正在監聽哪個埠?

可以通過IServerAddressesFeature.Addresses集合訪問 ASP.NET Core 應用程序的託管地址。

主要挑戰是在正確的時間呼叫將分析此集合的程式碼。實際的埠綁定發生在IWebHost.Run()被呼叫時(從Program.Main())。因此,您還不能在Startup.Configure()方法中訪問託管地址,因為此階段尚未分配埠。並且您在呼叫後失去控制IWebHost.Run(),因為此呼叫在虛擬主機關閉之前不會返回。

據我了解,分析綁定埠最合適的方法是通過實現IHostedService。這是工作範例:

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。我看不到其他方式如何將其註入服務中。

GitHub 上的範例項目

總的來說,我對這樣的解決方案不滿意。它完成了這項工作,但它似乎比它應該的要復雜得多。

引用自:https://stackoverflow.com/questions/49871318