我怀疑这是我正在尝试做的“奇怪”事情,但是...我已将Kestrel配置为侦听多个端口。有时候,这些端口之一已经在使用中。
这当前导致我的应用程序崩溃。
我想看到的行为是,它监听我指定的所有可用端口。但是我找不到关于该主题的任何示例/文档。
例如,我可以将其配置为在90、91、92、93上侦听...但是如果端口91已在使用中,我希望它仅在90、92、93端口上侦听。只要它可以继续,介意它是否会引发异常或记录错误。我想避免“先检查”,然后再更改配置,因为这感觉像是在等待比赛条件发生)
谁能告诉我如何允许Kestrel仅在可用端口上启动?
答案 0 :(得分:2)
您可以使用端口0 ;这样,Kestrel会在运行时动态绑定到可用端口,如here:
private static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.UseStartup<Startup>()
.UseUrls("http://*:0");
此外,您可以像这样确定运行时实际上绑定了哪个端口Kestrel:
public static void Main(string[] args)
{
IWebHost webHost = CreateWebHostBuilder(args).Build();
webHost.Start();
string address = webHost.ServerFeatures
.Get<IServerAddressesFeature>()
.Addresses
.First();
int port = int.Parse(address.Split(':')[4]);
}
更新:
如果其他应用程序未使用指定的端口,则可以检查端口的可用性并启动项目:
private static string[] GenerateUrls(IEnumerable<int> ports)
{
return ports.Select(port => $"http://localhost:{port}").ToArray();
}
private static IEnumerable<int> GetAvailablePorts(IEnumerable<int> ports)
{
IPGlobalProperties ipGlobalProperties = IPGlobalProperties.GetIPGlobalProperties();
IPEndPoint[] tcpConnInfoArray = ipGlobalProperties.GetActiveTcpListeners();
IEnumerable<int> allActivePorts = tcpConnInfoArray.Select(endpoint => endpoint.Port).ToList();
return ports.Where(port => !allActivePorts.Contains(port)).ToList();
}
最终结果将是这样:
public static void Main(string[] args)
{
CreateWebHostBuilder(args).Build().Run();
}
private static IWebHostBuilder CreateWebHostBuilder(string[] args)
{
IWebHostBuilder webHost = WebHost.CreateDefaultBuilder(args)
.UseStartup<Startup>();
int[] ports = { 5000, 5050, 8585 };
IEnumerable<int> availablePorts = GetAvailablePorts(ports).ToList();
if (!availablePorts.Any())
throw new InvalidOperationException("There are no active ports available to start the project.");
webHost.UseUrls(GenerateUrls(availablePorts));
return webHost;
}