【发布时间】:2019-12-06 12:59:08
【问题描述】:
有了 ASP.NET Core 3.0,我已经能够使用这个IHostedService 方法...
Determine port Kestrel binded to
...在运行时确定 Kestrel 的动态端口。
IServerAddressesFeature 在此处记录了 ASP.NET 3.0:
但是当将版本更改为 ASP.NET Core 3.1 时,页面会重定向回 ASP.NET 3.0,并提示该文档不适用于 ASP.NET Core 3.1。 IServerAddressesFeature 不再工作了吗?在 ASP.NET Core 3.1 中使用 IServerAddressesFeature 仍然可以编译,但返回的 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)
{
await System.Threading.Tasks.Task.Delay(250);
var address = ServerAddresses.Addresses.FirstOrDefault();
if (string.IsNullOrEmpty(address))
continue;
// address is always in form http://127.0.0.1:port
var pos = address.LastIndexOf(':');
if (pos > 0)
{
var portString = address.Substring(pos + 1);
port = int.Parse(portString);
}
}
// have determined the dynamic port now
});
return System.Threading.Tasks.Task.CompletedTask;
}
【问题讨论】:
标签: c# asp.net-core asp.net-core-3.1