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

Asp.Net: send SignalR message on Application_End

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

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

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 消息?

也许你可以尝试 IRegisteredObject 存在于 System.Web.Hosting 命名空间中。

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

创建一个 class TerminationCommand 实现 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);
    }
}

接下来我们需要在Application_Start部分

注册我们的TerminationCommandclass
protected void Application_Start()
{
    //Existing code.
    HostingEnvironment.RegisterObject(new TerminationCommand());
}

参考资料

IRegisteredObject

HostingEnvironment.Registered method