Cannot read property 'client' of undefined using SignalR

9.2k views Asked by At

I've been working all day on this with no luck. I have also tried (almost) every single SO question, but I didn't get it to work...

I'm running web api with very simple SignalR push message and separately simple front end to show this push message. In my case the push message is constantly changing number.

index.html

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title>test app</title>

    <script src="scripts/jquery-2.1.4.js"></script>
    <script src="scripts/jquery.signalR-2.2.0.js"></script>

    <script src="/signalr/hubs"></script>
</head>
<body>
    <div id="testElm">TEST: </div>

    <script type="text/javascript">
        $(document).ready(function () {

            $.connection.hub.url = "http://localhost:55833/signalr";
            var hub = $.connection.displayHub;

            hub.client.pushMessage = function (response) {

                $('#testElm').text(response);
            };

            $.connection.hub.start();
        });
    </script>
</body>
</html>

my hub class

public class DisplayHub : Hub
{
    public DisplayHub() : this(GlobalHost.ConnectionManager.GetHubContext<DisplayHub>().Clients) { }

    public DisplayHub(IHubConnectionContext<dynamic> clients)
    {
    }

    public void PushMessage(string message)
    {
        // generate random number and send it every 1s for testing

        Clients.All.pushMessage(randomNumber);
    }
}

When running with

$.connection.hub.logging = true;

this is the log I'm getting

2015-06-15 16:44:15 GMT+0100 (GMT Daylight Time)] SignalR: Auto detected cross domain url.
2015-06-15 16:44:15.314 jquery.signalR-2.2.0.js:81 [16:44:15 GMT+0100 (GMT Daylight Time)] SignalR: Negotiating with 'http://localhost:55833/signalr/negotiate?clientProtocol=1.5'.
2015-06-15 16:44:15.434 jquery.signalR-2.2.0.js:81 [16:44:15 GMT+0100 (GMT Daylight Time)] SignalR: webSockets transport starting.
2015-06-15 16:44:15.435 jquery.signalR-2.2.0.js:81 [16:44:15 GMT+0100 (GMT Daylight Time)] SignalR: Connecting to websocket endpoint 'ws://localhost:55833/signalr/connect?transport=webSockets&clientProtocol=1.5&connectionToken=h7UAGOrF6RP8JUE%2F82K84E8NSZOd8jsuijsCQ2Jyh1jRi7zXmIpoVnIP9tjEjlcWvxihtZBNt6BYdaAW2jp574B5nXS%2BJFEW%2F%2BdixsiV0yu3YwaN5ERh6yhYtkvztQSQ&tid=5'.
2015-06-15 16:44:15.451 jquery.signalR-2.2.0.js:81 [16:44:15 GMT+0100 (GMT Daylight Time)] SignalR: Websocket opened.
2015-06-15 16:44:15.510 jquery.signalR-2.2.0.js:81 [16:44:15 GMT+0100 (GMT Daylight Time)] SignalR: webSockets transport connected. Initiating start request.
2015-06-15 16:44:15.518 jquery.signalR-2.2.0.js:81 [16:44:15 GMT+0100 (GMT Daylight Time)] SignalR: The start request succeeded. Transitioning to the connected state.
2015-06-15 16:44:15.518 jquery.signalR-2.2.0.js:81 [16:44:15 GMT+0100 (GMT Daylight Time)] SignalR: Now monitoring keep alive with a warning timeout of 13333.333333333332, keep alive timeout of 20000 and disconnecting timeout of 30000

and I keep getting

Cannot read property 'client' of undefined
  • checking "hub" will show hub is undefined ...
  • browsing to http://localhost:55833/signalr/hubs I can see hub on the server being created.
  • temporarily merging API and front end, all will work fine, but if I keep them separate I will get above error...
  • using [HubName("displayHub")] attribute made no difference.
  • CORS is set up correctly as per the log above

Any ideas what is causing the error? Is there a way I can debug signalR further to find out what is going on?

Update 1:

after reading ASP.NET SignalR Hubs API Guide - JavaScript on http://www.asp.net/signalr/overview/guide-to-the-api/hubs-api-guide-javascript-client I have changed my code as per Without the generated proxy paragraph to:

var conn = $.hubConnection("http://localhost:55833/signalr");
var hubProxy = conn.createHubProxy('displayHub');

hubProxy.on('pushMessage', function (response) {
    $('#testElm').text(response);
});

conn.start();

and it started to work... Can someone explain why?

2

There are 2 answers

2
Wasp On BEST ANSWER

From your question I understand you have 2 different applications for client and server, and you are using CORS. The reason why your first attempt did not work is that you did not make the dynamic SignalR endpoint target the server application. You should have changed this:

<script src="/signalr/hubs"></script>

into this:

<script src="http://localhost:55833/signalr/hubs"></script>

The reason is, that endpoint dynamically generates Javascript code representing the shape of your hubs, therefore it needs to be called on the application where the hubs are, hence the server.

0
AudioBubble On

You also can get this error, if your signalr project does not load at runtime. e.g. it is missing an assembly. The full host prefix, is not required, so including /signalr/hubs should be sufficient.