asp.net-core - 防止 Kestrel 在端口使用时崩溃
问题描述
我怀疑这是我正在尝试做的一件“奇怪”的事情,但是......我已经将 Kestrel 配置为监听多个端口。问题是,有时,其中一个端口已经在使用中。
这目前导致我的应用程序崩溃。
我希望看到的行为是它侦听我指定的所有可用端口。但我无法找到有关该主题的任何示例/文档。
例如,我可以将其配置为侦听 90、91、92、93……但如果端口 91 已在使用中,我希望它仅侦听端口 90、92、93。我不介意它是否抛出异常或记录错误,只要我可以让它继续。我想避免“先检查”然后更改配置,因为这感觉就像等待发生的竞争条件)
谁能告诉我如何让 Kestrel 仅在可用端口上启动?
解决方案
您可以使用端口 0;这样,Kestrel在运行时动态绑定到可用端口,如下所述:
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;
}
推荐阅读
- c# - 如何使用标签助手将整个模型传递给部分视图
- python - 无法将“sys.executable”路径与另一个文件连接
- python-3.x - 如何在 OpenCV 中屏蔽图像。然后将图像反转成二进制数组
- postgresql - Postgresql pg_basebackup 和 archive_command
- javascript - 模态表单标签标签中的引导工具提示不起作用
- sphinx - Manticore - JSON 的 FACET,使用 JSON 数组的键
- google-play - 公测版和正式版之间的区别
- java - Duration.between vs ChronoUnit.between
- javascript - 如何在不预览且不更改nuxt项目页面的情况下下载pdf结果?
- python - Pytest 收集测试失败