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?
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:
into this:
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.