Asp.Net:在Application_End上发送SignalR消息

Asp.Net: send SignalR message on Application_End

我有一个标准的Web窗体应用程序,该应用程序包括一个用于JavaScript客户端的SignalR集线器。集线器本身可以正常工作,并且按预期方式发送和接收消息。

当应用程序终止时(通常是通过应用程序池回收),我想向所有连接的SignalR客户端发送一条特定的消息。
所以我像这样钩住了Global.asax的Application_End:

1
2
3
4
5
6
7
8
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");
            });
}

嗯...这行不通。如果我将代码放在Application_End之外,则它可以正常工作,并且客户端会收到该消息。
我的猜测是SignalR自动检测到应用程序关闭并终止所有连接。我还没有找到任何文档可以验证。

所以我的问题是:在应用程序关闭之前,如何发送自动SignalR消息?


也许您可以尝试在System.Web.Hosting命名空间中使用IRegisteredObject

首先,我们创建一个实现IRegisteredObject接口的对象,并通过调用HostingEnvironment.RegisterObject在ASP.NET托管环境中对其进行注册。在即将卸载应用程序域的情况下,ASP.NET托管环境将调用IRegisteredObjectStop方法实现。

创建一个实现IRegisteredObject

的类TerminationCommand

1
2
3
4
5
6
7
8
9
10
11
12
13
14
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);
    }
}

接下来,我们需要在Application_Start部分中注册我们的TerminationCommand

1
2
3
4
5
protected void Application_Start()
{
    //Existing code.
    HostingEnvironment.RegisterObject(new TerminationCommand());
}

参考文献

IRegisteredObject

HostingEnvironment。注册方法