J.R*_*.R. 7 c# asp.net-core asp.net-core-3.1
使用 ASP.NET Core 3.0 我已经能够使用这种IHostedService方法......
...在运行时确定 Kestrel 的动态端口。
IServerAddressesFeatureASP.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();
}
Run Code Online (Sandbox Code Playgroud)
后来,什么时候Configure叫...
    public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    {
        HostedService.ServerAddresses = app.ServerFeatures.Get<Microsoft.AspNetCore.Hosting.Server.Features.IServerAddressesFeature>();
Run Code Online (Sandbox Code Playgroud)
...服务器地址被分配给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;
        }
Run Code Online (Sandbox Code Playgroud)
    IHostedService方法不起作用的原因是.Net Core 3在执行IHostedServices时发生了变化。在.Net Core 2中,IHostedService在主机启动后执行,因此服务器地址信息很容易获得。在.Net Core 3中,IHostedService在主机构建之后、主机启动之前且地址尚未可用之前运行。 这个博客对发生的变化有很好的解释。
以下获取绑定地址的方法(从此处复制)适用于 .Net Core 2 和 3。
您可以致电,IWebHost.Start()而不是按照此处的IWebHost.Run()建议进行。这将允许您的方法继续执行,以便您可以从中获取所需的信息。请记住,您的应用程序将立即关闭,除非您明确告诉它不要使用.MainIWebHost.ServerFeaturesIWebHost.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();
    }
Run Code Online (Sandbox Code Playgroud)
        |   归档时间:  |  
           
  |  
        
|   查看次数:  |  
           2882 次  |  
        
|   最近记录:  |