How can I know when Kestrel has started listening?

假如想象 提交于 2020-01-22 14:59:25

问题


I need to notify systemd that my service has started up successfully, and a task it needs to run after startup requires that the server is already listening on the target Unix domain socket.

I am using IWebHost::Run to start the server, and that is a blocking call. Additionally, I am unable to find any obvious way to set a delegate or callback event for successful initialization.

Anyone?


回答1:


  • On .Net Core 1.x it is safe to just run IWebHost.Start() and assume that the server is initialized afterwards (instead of Run() that blocks the thread). Check the source.

    var host = new WebHostBuilder()
        .UseKestrel()
        (...)
        .Build();
    
    host.Start();
    
  • If you are using .NET Core 2.0 Preview 1 (or later), the source is different, the synchronous method is not available anymore so you should await IWebHost.StartAsync() and assume everything is ready afterwards.




回答2:


You may use Microsoft.AspNetCore.Hosting.IApplicationLifetime:

/// <summary>
/// Triggered when the application host has fully started and is about to wait
/// for a graceful shutdown.
/// </summary>
CancellationToken ApplicationStarted { get; }

Look into this SO post for the configuration example.




回答3:


This is what I ended up going with, for now. Seems to be working fine:

host.Start();

Log.Information("Press Ctrl+C to shut down...");
Console.CancelKeyPress += OnConsoleCancelKeyPress;

var waitHandles = new WaitHandle[] {
    CancelTokenSource.Token.WaitHandle
};

WaitHandle.WaitAll(waitHandles);
Log.Information("Shutting down...");

Then, in the Ctrl+C event handler:

private static void OnConsoleCancelKeyPress(object sender, ConsoleCancelEventArgs e)
{
    Log.Debug("Got Ctrl+C from console.");
    CancelTokenSource.Cancel();
}



回答4:


This is what I did to overcome the issue.

1- I registered ApplicationStopped event. So that it brute force terminates the app by calling Kill() method of the current process.

public void Configure(IHostApplicationLifetime appLifetime) {
 appLifetime.ApplicationStarted.Register(() => {
  Console.WriteLine("Press Ctrl+C to shut down.");
 });

 appLifetime.ApplicationStopped.Register(() => {
  Console.WriteLine("Terminating application...");
  System.Diagnostics.Process.GetCurrentProcess().Kill();
 });
}

See IHostApplicationLifetime docs


2- Don't forget to use the UseConsoleLifetime() while building the host.

Host.CreateDefaultBuilder(args).UseConsoleLifetime(opts => opts.SuppressStatusMessages = true);

See useconsolelifetime docs



来源:https://stackoverflow.com/questions/44662711/how-can-i-know-when-kestrel-has-started-listening

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!