Asp.net-Core
確定 Kestrel 綁定到的埠
我正在使用 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。我看不到其他方式如何將其註入服務中。總的來說,我對這樣的解決方案不滿意。它完成了這項工作,但它似乎比它應該的要復雜得多。