问题
I need to start 2 Kestrel servers from a Console application. The code below shows how I'm doing it now.
Unfortunately, both servers attempt to start on the same ports HTTP:5000
and HTTPS:5001
and only first one is actually started.
I also tried to specify URLs in appsettings.json
but it doesn't work as expected and I wouldn't like to hardcode server URLs, because if I restart Console app it doesn't kill previously started servers and can't start them again.
Question
How to find free ports for HTTP and HTTPS for both servers from code and make sure that they are different?
Server
public class WebServer { public static IWebHost Run<TStartup>(WebOptions options = null) { var configuration = new ConfigurationBuilder().Build(); var environment = WebHost .CreateDefaultBuilder(new string[0]) .ConfigureServices(o => o.AddSingleton(options)) .UseConfiguration(configuration) .UseContentRoot(Directory.GetCurrentDirectory()) .UseKestrel() .UseStartup<TStartup>() .Build(); environment.RunAsync(); return environment; } } var serviceEnvironment = Server.Run<ServiceStartup>(); var webEnvironment = Server.Run<WebStartup>(); var serviceAddresses = serviceEnvironment.ServerFeatures.Get<IServerAddressesFeature>().Addresses; var webAddresses = webEnvironment.ServerFeatures.Get<IServerAddressesFeature>().Addresses;
回答1:
You can bind to port 0 and Kestrel will find a random available port automatically.
From the Microsoft docs for Kestrel:
When the port number 0 is specified, Kestrel dynamically binds to an available port. The following example shows how to determine which port Kestrel actually bound at runtime:
public void Configure(IApplicationBuilder app) { var serverAddressesFeature = app.ServerFeatures.Get<IServerAddressesFeature>(); app.UseStaticFiles(); app.Run(async (context) => { context.Response.ContentType = "text/html"; await context.Response .WriteAsync("<!DOCTYPE html><html lang=\"en\"><head>" + "<title></title></head><body><p>Hosted by Kestrel</p>"); if (serverAddressesFeature != null) { await context.Response .WriteAsync("<p>Listening on the following addresses: " + string.Join(", ", serverAddressesFeature.Addresses) + "</p>"); } await context.Response.WriteAsync("<p>Request URL: " + $"{context.Request.GetDisplayUrl()}<p>"); }); }
来源:https://stackoverflow.com/questions/62602901/find-2-different-free-ports-for-2-kestrel-servers