The problem seems to be with your Access-Control-Allow-Origin
header.
map.UseCors(CorsOptions.AllowAll);
The above line should cause every response to a SignalR CORS request to have the following header:
Access-Control-Allow-Origin: (request origin)
In your case, the (request origin) should be http://localhost:50709
, but instead it is http://localhost:50709, *
judging by the following log output:
[18:06:41 GMT-0600 (Central Standard Time)] SignalR: Negotiating with 'http://localhost:60601/signalr/negotiate?connectionData=%5B%7B%22name%22%3A%22chathub%22%7D%5D&clientProtocol=1.3'.
HTMLHttpRequest cannot load http://localhost:60601/signalr/negotiate?connectionData=%5B%7B%22name%22%3A%22chathub%22%7D%5D&clientProtocol=1.3&_=1386201997462.
The 'Access-Control-Allow-Origin' header contains the invalid value 'http://localhost:50709, *'. Origin 'http://localhost:50709' is therefore not allowed access.
SignalR error: Error: Error during negotiation request.
This is most likely caused by something similar to the following in your web.config:
<httpProtocol>
<customHeaders>
<add name="Access-Control-Allow-Origin" value="*" />
</customHeaders>
</httpProtocol>
Or perhapse something similar to the following in your middleware code:
Response.AppendHeader("Access-Control-Allow-Origin", "*");
Either way, since you are already using map.UseCors(CorsOptions.AllowAll);
you should not be setting the Access-Control-Allow-Origin
header elsewhere.
Note about JSONP
Lastly, I know you probably only did this for debugging purposes, but starting the connection like so: $.connection.hub.start({ jsonp: true, transport: 'webSockets' })
probably isn't the best idea.
With these settings, the negotiate request (and any long polling requests) will always be made with JSONP, not CORS. This might make sense when you can't get CORS to work, but if you can get CORS working you should use that instead and not enable JSONP since CORS allows for more fine-grained access control configuration.
If you set EnableJSONP
to true on the server, you are allowing JS code running on any website to access your SignalR service no matter what you set your CorsOptions
to.
If you decide to leave JSONP enabled on the server, there is no reason to specify jsonp: true
in the configuration object you pass to hub.start
since SignalR should fall back and try to use JSONP if CORS requests fail.
The same goes for specifying transport: 'webSockets'
. By default, SignalR will try to use the WebSocket transport first if it's available.