Search code examples
asp.netsignalrexitsignalr-hub

Asp.Net: send SignalR message on Application_End


I have a standard Web Forms application that includes a SignalR hub for JavaScript clients. The hub itself works fine and messages are being sent and received as expected.

When the application is terminated (usually via application pool recycling), I want to send a specific message to all connected SignalR clients. So I hooked into Global.asax's Application_End like this:

void Application_End(object sender, EventArgs e)
{
            var hubNotifyTask = Task.Factory.StartNew(() =>
            {
                 IHubContext context = GlobalHost.ConnectionManager.GetHubContext<SiteMasterJsClientHub>();
                 context.Clients.Group("Group with all users").OnServerStartup("any message");
            });
}

Well...this doesn't work. If i put the code outside of Application_End, it works and the clients receive the message. My guess is that SignalR auto-detects the application shutdown and terminates all connections. I haven't found any documentation to verify that though.

So my question is: how can I send an automatic SignalR message just before the application shuts down?


Solution

  • Maybe you can try IRegisteredObject present in System.Web.Hosting namespace.

    First we create an object that implements IRegisteredObject interface and register it with ASP.NET hosting environment by calling HostingEnvironment.RegisterObject. With that in place when the app domain is about to unloaded, the ASP.NET hosting environment will call the Stop method implementation of IRegisteredObject.

    Create a class TerminationCommand which implements IRegisteredObject

    public class TerminationCommand : IRegisteredObject
    {
        private readonly IHubContext siteMasterJsClientHub;
        public TerminationCommand()
        {
            siteMasterJsClientHub = GlobalHost.ConnectionManager.GetHubContext<SiteMasterJsClientHub>();
        }
    
        public void Stop(bool immediate)
        {
            siteMasterJsClientHub.Clients.Group("Group with all users").OnServerStartup("any message");
            HostingEnvironment.UnregisterObject(this);
        }
    }
    

    Next we need to register our TerminationCommand class in Application_Start section

    protected void Application_Start()
    {
        //Existing code.
        HostingEnvironment.RegisterObject(new TerminationCommand());
    }
    

    References

    IRegisteredObject

    HostingEnvironment.Registered method