简体   繁体   中英

SignalR separated events for multiple hubs

I'm trying to set up some SignalR Hubs and some separate OnDisconnected events for them.

For the sake of the question, on some page I have two Hubs:

  1. StatusHub: Handles the status of the user on the website. This hub's methods are called on every page of the website and hadle the logic of the user connection and disconnection to update the user status as he navigates through the WebSite.

  2. ChatHub: Handles everything related to the website real time chat. This hub's methods are only called from a specific page of the website, when the user click on specific buttons.

The problem I'm experiencing is that even though both of the hub classes implement their own version of the OnConnected and OnDisconnected methods, only the StatusHub methods are fired, the ChatHub methods aren't being called.

I don't know if that is by design, or if I'm doing something wrong. So far I've read some articles and answers that states that the connection to the hub server is a single connection and that I don't connect to a specific hub, I connect to the Hub server as a whole so only one of the methods will ever be recognized and called.

Can anyone with more experience with SignalR tell me if there is a way to separate the connection and disconnection events of the two hubs or if that's really meant to be this way?

I'll put just a few some pieces of code below to better illustrate the scenario but if you need to see more code, just ask and I'll add it.

StatusHub.cs

public class StatusHub : Hub { 
    public override Task OnDisconnected()
    {
        //handles the disconnected event as needed
        return base.OnDisconnected();
    }


    public override Task OnConnected()
    {
        //handles the connected event as needed
        return base.OnConnected();
    }
}

ChatHub.cs

public class ChatHub : Hub { 
    public override Task OnDisconnected()
    {
        //should handle the chat disconnected event but is never reached
        return base.OnDisconnected();
    }


    public override Task OnConnected()
    {
        //should handle the chat connected event but is never reached
        return base.OnConnected();
    }
}

Code that starts the hub server connection (executed on every page):

$.connection.hub.start().done(function() {
    //a lot of code here (irrelevant to the question I think)
});

Have you resolved this? What you describe very much seems like an issue with not registering any client method for the ChatHub . When no client methods are registered, the client can invoke a hub method on the server, and will get the result (very similar to request-response nature of the stateless protocols), but since there is no way for the server to call anything on the client without being requested to provide response (by the means of client invoking the hub method), it is by design that such connections don't trigger the OnConnected , OnReconnected and OnDisconnected overloads.

The solution is fairly simple, it is enough to register a no-op client method like this:

$(function()
{
  // A no-op client method so the hub's
  // OnConnected, OnReconnected and OnDisconnected method overloads are triggered.
  $.connection.chatHub.client.noop = function () { };
  $.connection.hub.start()
    .done(function() { console.log("SignalR connection is up and running."); })
    .fail(function(error) { console.log(error); });
});

I don't know the exact reasoning that went into this, but the overloads, that are usually used to keep track of connected clients and possibly associating them with abstractions (something SignalR groups cannot provide since they are not enumerable) are fairly useless for the connections you cannot poke back, so that's my two cents on why it has to be done this way.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM