Search code examples
angularjssignalrsignalr-hub

SignalR server doesn't consistently call methods on client


I have an AngularJS application that I intend to have receive communications via SignalR from the server, most notably when data changes and I want the client to refresh itself.

The following is my hub logic:

[HubName("update")]
    public class SignalRHub : Hub
    {
        public static void SendDataChangedMessage(string changeType)
        {
            var context = GlobalHost.ConnectionManager.GetHubContext<SignalRHub>();
            context.Clients.All.ReceiveDataChangedMessage(changeType);
        }
    }

I use the following within my API after the data operation has successfully occurred to send the message to the clients:

SignalRHub.SendDataChangedMessage("newdata");

Within my AngularJS application, I create a service for SignalR with the following javascript that's referenced in the HTML page:

angular.module('MyApp').value('signalr', $.connection.update);

Within the root for the AngularJS module, I set this up with the following so that it starts and I can see the debug output:

$(function () {
    $.connection.hub.logging = true;
    $.connection.hub.start();
});

$.connection.hub.error(function(err) {
    console.log('An error occurred: ' + err);
});

Then I've got my controller. It's got all sorts of wonderful things in it, but I'll show the basics as relate to this issue:

angular.module('MyApp').controller('MyController', function($scope, signalr) {
  signalr.client.ReceiveDataChangedMessage = function dataReceived(changeType) {
    console.log('DataChangedUpdate: ' + changeType);
  };
});

Unfortunately, when I set a breakpoint in the javascript, this never executes though the rest of the program works fine (including performing the operation in the API).

Some additional (hopefully) helpful information:

  • If I set a breakpoint in the SignalRHub class, the method is successfully called as expected and throws no exceptions.

  • If I look at Fiddler, I can see the polling operations but never see any sign of the call being sent to the client.

  • The Chrome console shows that the AngularJS client negotiates the websocket endpoint, it opens it, initiates the start request, transitions to the connected state, and monitors the keep alive with a warning and connection lost timeout. There's no indication that the client ever disconnects from the server.

  • I reference the proxy script available at http://localhost:port/signalr/hubs in my HTML file so I disregard the first error I receive stating that no hubs have been subscribed to. Partly because the very next message in the console is the negotiation with the server and if I later use '$.connection.hub' in the console, I'll see the populated object.

I appreciate any help you can provide. Thanks!


Solution

  • It's not easy to reproduce it here, but it's likely that the controller function is invoked after the start of the connection. You can verify with a couple of breakpoints on the first line of the controller and on the start call. If I'm right, that's why you are not called back, because the callback on the client member must be defined before starting the connection. Try restructuring your code a bit in order to ensure the right order.