gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-12-01 16:02:30 46 4
gpt4 key购买 nike

通过 ASP.NET Core 3.0,我已经能够使用这个 IHostedService 方法...

Determine port Kestrel binded to

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

IServerAddressesFeature 的 ASP.NET 3.0 文档如下:

https://learn.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 配置为使用随机动态端口并确定其在运行时(发生任何 Controller 操作之前)的端口?

更新

这是一个丑陋的解决方法,可以帮助确定端口。动态端口分配的时间或顺序似乎已更改。从 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;
}

最佳答案

IHostedService方法不起作用的原因是.Net Core 3在执行IHostedServices时发生了变化。在.Net Core 2中,IHostedService在主机启动后执行,因此服务器地址信息很容易获得。在.Net Core 3中,IHostedService在主机构建之后、主机启动之前且地址尚未可用之前运行。 This blog对发生的变化有很好的解释。

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

您可以按照建议调用 IWebHost.Start() 而不是 IWebHost.Run() here 。这将允许继续执行 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();
}

关于c# - 如何将 Kestrel 配置为使用随机动态端口并在 ASP.NET Core 3.1 运行时确定端口?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59213674/

46 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com