.NET Core 6.0 - 获取 Kestrel 动态绑定的端口(端口 0)

4

背景

".NET 6"中的"托管"机制已经改变。之前,IWebHost拥有IWebHost.ServerFeatures属性,该属性可用于获取IServerAddressFeature,例如(来自此SO答案):

IWebHost 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}");
}

问题:如何在.NET 6中使用IHost获取端口号?

现在我有一个IHost,如何获取端口号(在???处):

public class Program {
  public static void Main(string[] args) {
    IHostBuilder hostBuilder = Host.CreateDefaultBuilder(args);
    hostBuilder.ConfigureWebHostDefaults(webHostBuilder => {
      webHostBuilder.ConfigureKestrel(opts => {
        opts.ListenAnyIP(0); // bind web server to random free port
      });
      webHostBuilder.UseStartup<Startup>();
    });
    IHost host = hostBuilder.Build();
    host.Start();
    // If it doesn't fail, at this point Kestrel has started
    // and is listening on a port. It even prints the port to
    // console via logger.
    int boundPort = ???; // some magic GetPort(IHost host) method

    // This link in the docs mentions getting the port, but the example
    // they provide is incomplete
    // https://learn.microsoft.com/en-us/aspnet/core/fundamentals/servers/kestrel/endpoints?view=aspnetcore-6.0#port-0
    host.WaitForShutdown();
  }
}

来自Microsoft文档的示例:

当指定端口号为0时,Kestrel会动态绑定到一个可用端口。以下示例显示如何在运行时确定Kestrel绑定的端口号:

app.Run(async (context) =>
{
    var serverAddressFeature = context.Features.Get<IServerAddressesFeature>();

    if (serverAddressFeature is not null)
    {
        var listenAddresses = string.Join(", ", serverAddressFeature.Addresses);

        // ...
    }
});

在这个例子中,什么是app?我在哪里可以获得那个带有.Featurescontext
1个回答

5

在发布问题后,找到了一个有效的答案。这是一个在.NET 6中打印运行Web服务器地址(包括端口)的功能。原来我们对主机中一个正在运行中的IServer服务实例感兴趣。

public static void PrintBoundAddressesAndPorts(IHost host)
{
    Console.WriteLine("Checking addresses...");
    var server = host.Services.GetRequiredService<IServer>();
    var addressFeature = server.Features.Get<IServerAddressesFeature>();
    foreach(var address in addressFeature.Addresses)
    {
        var uri = new Uri(address);
        var port = uri.Port;
        Console.WriteLine($"Listing on [{address}]");
        Console.WriteLine($"The port is [{port}]");
    }
}

在这篇文章中找到了答案:https://andrewlock.net/finding-the-urls-of-an-aspnetcore-app-from-a-hosted-service-in-dotnet-6/。该文章介绍了如何从托管服务中获取ASP.NET Core应用程序的URL。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接