.NET Core 6.0 - 获取Kestrel的动态绑定端口(端口0)
.NET Core 6.0 - Get Kestrel's dynamically bound port (port 0)
上下文
“托管”机制在 .NET 6 中发生了变化。以前 IWebHost
有 IWebHost.ServerFeatures
属性 可以用来像这样获取 IServerAddressFeature
(来自):
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}");
}
问题:如何使用 IHost 在 .NET 6 中获取端口?
现在在 .NET 6 中我有一个 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://docs.microsoft.com/en-us/aspnet/core/fundamentals/servers/kestrel/endpoints?view=aspnetcore-6.0#port-0
host.WaitForShutdown();
}
}
微软文档中的示例:
指定端口号 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
是什么?我在哪里可以用 .Features
得到 context
?
发布问题后立即找到有效答案。
在 .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/
上下文
“托管”机制在 .NET 6 中发生了变化。以前 IWebHost
有 IWebHost.ServerFeatures
属性 可以用来像这样获取 IServerAddressFeature
(来自
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}");
}
问题:如何使用 IHost 在 .NET 6 中获取端口?
现在在 .NET 6 中我有一个 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://docs.microsoft.com/en-us/aspnet/core/fundamentals/servers/kestrel/endpoints?view=aspnetcore-6.0#port-0
host.WaitForShutdown();
}
}
微软文档中的示例:
指定端口号 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
是什么?我在哪里可以用 .Features
得到 context
?
发布问题后立即找到有效答案。
在 .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/