1

I am trying to create a JQuery UI widget that receives realtime updates from a server using SignalR (2.2.0). Invoking a method on the server works just fine, however invoking a client callback from the server does not trigger on the client.

I have enabled logging on the client as is suggested here: SignalR Troubleshooting and I can see in the console that the connection is setup just fine but the client method is never invoked. There is no error message of any kind. I have also defined the client method on the hub proxy before starting the connection like so:

_bindClientCallbacks: function () {
    theHub.client.broadCastToClient = function (message) {
        twr.log(message);
    };
}

and afterwards I start the hub connection like so:

_startSignalRClient: function () {
    $.connection.hub.logging = true;
    $.connection.hub.start()
        .done(function () {
            twr.log("Connected to SignalR hub, id=" + $.connection.hub.id);
        })
        .fail(function () {
        });
}

These methods are called in the '_create()' function in the JQuery widget like so:

_create: function () {
    theHub = $.connection.DataImportHub;
    this._bindClientCallbacks();
    this._startSignalRClient();
} 

This works fine and I can get a valid connection with an id. I can also call a server method from the client. But when I try to invoke the broadCastToClient method on the client from the server like so:

public void BroadCastToClient(string userId, string message)
{
    var hubContext = GlobalHost.ConnectionManager.GetHubContext<DataImportHub>();
    foreach (var connectionId in _connections.GetConnections(userId))
    {
        hubContext.Clients.Client(connectionId).broadCastToClient(message);
    }
}

Nothing happens on the client.. even though the server does find a valid connection that corresponds to the connection id I got on the client.

What am I missing here?

lange
  • 21
  • 4
  • Ensure that `_bindClientCallbacks` is called before `_startSignalRClient`... – ViRuSTriNiTy Aug 26 '16 at 10:01
  • I call the _bindClientCallbacks before the _startSignalRClient in the _create function of the JQuery UI widget (I added the function to the post for clarification).. so I don't think that's the problem – lange Aug 26 '16 at 10:05
  • `hubContext.Clients.Client()` cannot be resolved on my machine, try `hubContext.Client()` instead. – ViRuSTriNiTy Aug 26 '16 at 10:11
  • The IHubContext interface only exposes properties Clients and Groups, so I cannot call Client() on it. I tried sending the message to hubContext.Clients.All but that also does not trigger the callback.. – lange Aug 26 '16 at 10:21
  • Just a question why don't you use `huContext.Clients.All.broadCastToClient(message);` ? – Mathieu Aug 26 '16 at 10:38
  • @Mathieu Because this would send the message to **all** clients. – ViRuSTriNiTy Aug 26 '16 at 10:39
  • @Mathieu Yes. I am performing a task for a specific user on the server and the updates I am sending to the client are only relevant for that user – lange Aug 26 '16 at 10:44
  • @lange Try the SignalR stuff in a simple `` section first. Your code looks ok to me, it should work. – ViRuSTriNiTy Aug 26 '16 at 10:45
  • Sorry I was in error due to the foreach, my bad – Mathieu Aug 26 '16 at 11:15
  • putting everything in a simplified block yields the same result. Connection is fine, calling server method is fine, calling client method fails again. – lange Aug 26 '16 at 11:18

1 Answers1

0

Just found out the solution by reading this post. Apparently having a custom SignalR dependency resolver setup in the Owin startup class breaks javascript callbacks. Moving the dependency resolver setup code to Application_Start in Global.asax does the trick. Why this happens really is beyond me...

Bad DI setup in Startup.cs

app.Map("/signalr", map =>
{
    var hubConfiguration = new HubConfiguration
    {
        Resolver = new NinjectSignalRDependencyResolver(new StandardKernel())
    };
    map.RunSignalR(hubConfiguration);
});

Good DI setup in Global.asax

protected void Application_Start()
{
    GlobalHost.DependencyResolver = new NinjectSignalRDependencyResolver(new StandardKernel());
}
Community
  • 1
  • 1
lange
  • 21
  • 4