スタンドアロンアプリケーションとして実行する予定のASP.NETCore2.0アプリがあります。アプリが起動し、使用可能なポートにバインドする必要があります。これを実現するために、「 http://127.0.0.1: "」をリッスンし、Kestrelサーバーを使用するようにWebHostBuilderを構成します。ウェブホストがリッスンを開始したら、実際のポートを含むURLをファイルに保存したいと思います。別のアプリケーションがファイルを読み取ってアプリとやり取りするため、これをできるだけ早く実行したいと思います。
Webホストがリッスンしているポートを確認するにはどうすればよいですか?
これは、ConfigureメソッドのStartupクラスで実現できます。 IServerAddressesFeatureからポートを取得できます
コードの例を次に示します。
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory, ILogger<Startup> logger)
{
var serverAddressesFeature = app.ServerFeatures.Get<IServerAddressesFeature>();
loggerFactory.AddFile("logs/myfile-{Date}.txt", minimumLevel: LogLevel.Information, isJson: false);
logger.LogInformation("Listening on the following addresses: " + string.Join(", ", serverAddressesFeature.Addresses));
}
Start()
の代わりにRun()
メソッドを使用して、適切なタイミングでIServerAddressesFeature
にアクセスできます。
IWebHost webHost = new WebHostBuilder()
.UseKestrel(options =>
options.Listen(IPAddress.Loopback, 0)) // dynamic port
.Build();
webHost.Start();
string address = webHost.ServerFeatures
.Get<IServerAddressesFeature>()
.Addresses
.First();
int port = int.Parse(address.Split(':').Last());
webHost.WaitForShutdown();
次のコードを使用して、StartUp.csでそれを行うことができました。
int Url = new System.Uri(Configuration["urls"]).Port;
リフレクションを使ってそれを行うことができます(うーん!)。 IHostedService
を登録し、IServer
を挿入しました。 ListenOptions
のKestrelServerOptions
プロパティは内部であるため、リフレクションを使用して取得する必要があります。ホストされているサービスが呼び出されたら、次のコードを使用してポートを抽出します。
var options = ((KestrelServer)server).Options;
var propertyInfo = options.GetType().GetProperty("ListenOptions", BindingFlags.Instance | BindingFlags.NonPublic);
var listenOptions = (List<ListenOptions>)propertyInfo.GetValue(options);
var ipEndPoint = listenOptions.First().IPEndPoint;
var port = ipEndPoint.Port;
少なくとも.NetCore 3からは、IServer
を挿入して情報を取得できます。
using System;
using System.Linq;
using Microsoft.AspNetCore.Hosting.Server;
using Microsoft.AspNetCore.Hosting.Server.Features;
namespace MyApp.Controllers
{
public class ServerInfoController : Controller
{
public ServerInfoController (IServer server)
{
var addresses = server.Features.Get<IServerAddressesFeature>()?.Addresses?.ToArray();
}
}
}