SignalR client connection error (UWP & JavaScript Client) - c#

I have both, a simple UWP app running on local machine in Visual Studio and a simple AngularJS SPA. I have also an OWIN based self hosted server running in a Service Fabric Cluster. The server use web api and signalR.
When I'm hosting the Service Fabric Cluster on my local machine, the UWP app and the angular app can open a connection to a signalR hub on the server. When I'm hosting the Service Fabric Cluster on Azure, the clients are not able to connect to the signalR hub. I'm getting: failed: Error during WebSocket handshake: Unexpected response code: 400
Server side code in startup class:
public void Configuration(IAppBuilder appBuilder)
{
HttpConfiguration httpConfig = this.ConfigureWebApi();
FileServerOptions fileServerOptions = this.ConfigureFileSystem(appBuilder); appBuilder.UseCors(Microsoft.Owin.Cors.CorsOptions.AllowAll);
appBuilder.UseWebApi(this.ConfigureWebApi());
appBuilder.UseFileServer(fileServerOptions);
appBuilder.MapSignalR();
SignalR hub class on server:
public class SensorDataHub : Hub
{
public void UpdateSensorData(SensorDataModel data)
{
Clients.All.updateChartData(data);
}
}
UWP code:
private async void OpenSignalRConnection()
{
//this.SensorDataHubCon = new HubConnection("http://localhost:80/");
this.SensorDataHubCon = new HubConnection("http://rivutec.westeurope.cloudapp.azure.com/");
this.SensorDataHubProxy = this.SensorDataHubCon.CreateHubProxy("SensorDataHub");
await this.SensorDataHubCon.Start();
}
AngularJS code:
var connection = $.hubConnection("http://localhost:80/");
//var connection = $.hubConnection("http://test.server.com/");
var proxy = connection.createHubProxy("SensorDataHub");
proxy.on("updateChartData", function (data) {
console.log(data.current);
});
connection.start()
.done(function () { console.log('Now connected, connection ID=' + $.connection.hub.id); })
.fail(function () { console.log('Could not Connect!'); });
As I wrote above, the UWP client and the angular client can open the hub connection to localhost.
But when I'm trying to connect the UWP client to a signalR hub published on a cloud, I'm getting a Bad Request error:
Microsoft.AspNet.SignalR.Client.HttpClientException was unhandled by user code
HResult=-2146233088
Message=StatusCode: 400, ReasonPhrase: 'Bad Request', Version: 1.1, Content: System.Net.Http.StreamContent, Headers:
{
Server: Microsoft-HTTPAPI/2.0
Transfer-Encoding: chunked
Date: Sun, 07 Feb 2016 13:59:09 GMT
X-Content-Type-Options: nosniff
}
Source=Microsoft.AspNet.SignalR.Client
StackTrace:
at Microsoft.AspNet.SignalR.Client.Http.DefaultHttpClient.<>c__DisplayClass6.<Post>b__5(HttpResponseMessage responseMessage)
at Microsoft.AspNet.SignalR.TaskAsyncHelper.<>c__DisplayClass19`2.<Then>b__17(Task`1 t)
at Microsoft.AspNet.SignalR.TaskAsyncHelper.TaskRunners`2.<>c__DisplayClass42.<RunTask>b__41(Task`1 t)
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.GetResult()
at SerialSample.MainPage.<OpenSignalRConnection>d__9.MoveNext()
InnerException:
And the signalR trace says:
13:59:02.3510728 - ac120389-8e08-4690-8e38-4538b602260e - SSE: GET http://test.server.com/signalr/connect?clientProtocol=1.4&transport=serverSentEvents&connectionData=[{"Name":"SensorDataHub"}]&connectionToken=AQAAANCMnd8BFdERjHoAwE%2FCl%2BsBAAAAVQGqCkfcnkONWeEawJYNqQAAAAACAAAAAAAQZgAAAAEAACAAAADhW4uMBq5ClXKT3X5UGNGLq3YzdxgD4blCiGSRFL8b8AAAAAAOgAAAAAIAACAAAABGZnghjduUUMHt3QMlhMxIRsajzvG0kWW4ECTpnppl4DAAAAALVIQ46T3%2BdnUpON%2FrpgZO8idns8YNkRrK9lMMxKQz7xYTgM8ViIcxeMNx7%2FamQsRAAAAA5KtFAgG0yKxNVlzAfGNc0cHP8NXxEmaK1i%2Blf52xb7SNmpz%2B5O%2BJxZmVz71Z3pdHV4Z1LyGJixJsRxnQEJOtfA%3D%3D&noCache=28c5a100-2796-4287-958b-0c2ccbd1e91a
The thread 0x4b04 has exited with code 0 (0x0).
13:59:07.3914634 - ac120389-8e08-4690-8e38-4538b602260e - Auto: Failed to connect to using transport serverSentEvents. System.TimeoutException: Transport timed out trying to connect
13:59:07.3994644 - ac120389-8e08-4690-8e38-4538b602260e - LP Connect: http://test.server.com/signalr/connect?clientProtocol=1.4&transport=longPolling&connectionData=[{"Name":"SensorDataHub"}]&connectionToken=AQAAANCMnd8BFdERjHoAwE%2FCl%2BsBAAAAVQGqCkfcnkONWeEawJYNqQAAAAACAAAAAAAQZgAAAAEAACAAAADhW4uMBq5ClXKT3X5UGNGLq3YzdxgD4blCiGSRFL8b8AAAAAAOgAAAAAIAACAAAABGZnghjduUUMHt3QMlhMxIRsajzvG0kWW4ECTpnppl4DAAAAALVIQ46T3%2BdnUpON%2FrpgZO8idns8YNkRrK9lMMxKQz7xYTgM8ViIcxeMNx7%2FamQsRAAAAA5KtFAgG0yKxNVlzAfGNc0cHP8NXxEmaK1i%2Blf52xb7SNmpz%2B5O%2BJxZmVz71Z3pdHV4Z1LyGJixJsRxnQEJOtfA%3D%3D&noCache=78a5c718-439d-440f-9b68-c0658135209f
'SerialSample.exe' (CoreCLR: CoreCLR_UWP_Domain): Loaded 'C:\Users\...\Downloads\samples-develop\samples-develop\SerialSample\CS\bin\x86\Debug\AppX\System.Net.Requests.dll'. Skipped loading symbols. Module is optimized and the debugger option 'Just My Code' is enabled.
13:59:07.5434999 - ac120389-8e08-4690-8e38-4538b602260e - Auto: Failed to connect to using transport longPolling. Microsoft.AspNet.SignalR.Client.HttpClientException: StatusCode: 400, ReasonPhrase: 'Bad Request', Version: 1.1, Content: System.Net.Http.StreamContent, Headers:
{
Server: Microsoft-HTTPAPI/2.0
Transfer-Encoding: chunked
Date: Sun, 07 Feb 2016 13:59:09 GMT
X-Content-Type-Options: nosniff
}
at Microsoft.AspNet.SignalR.Client.Http.DefaultHttpClient.<>c__DisplayClass6.<Post>b__5(HttpResponseMessage responseMessage)
at Microsoft.AspNet.SignalR.TaskAsyncHelper.<>c__DisplayClass19`2.<Then>b__17(Task`1 t)
at Microsoft.AspNet.SignalR.TaskAsyncHelper.TaskRunners`2.<>c__DisplayClass42.<RunTask>b__41(Task`1 t)
13:59:07.5755002 - ac120389-8e08-4690-8e38-4538b602260e - OnError(Microsoft.AspNet.SignalR.Client.HttpClientException: StatusCode: 400, ReasonPhrase: 'Bad Request', Version: 1.1, Content: System.Net.Http.StreamContent, Headers:
{
Server: Microsoft-HTTPAPI/2.0
Transfer-Encoding: chunked
Date: Sun, 07 Feb 2016 13:59:09 GMT
X-Content-Type-Options: nosniff
}
at Microsoft.AspNet.SignalR.Client.Http.DefaultHttpClient.<>c__DisplayClass6.<Post>b__5(HttpResponseMessage responseMessage)
at Microsoft.AspNet.SignalR.TaskAsyncHelper.<>c__DisplayClass19`2.<Then>b__17(Task`1 t)
at Microsoft.AspNet.SignalR.TaskAsyncHelper.TaskRunners`2.<>c__DisplayClass42.<RunTask>b__41(Task`1 t))
13:59:07.6070094 - ac120389-8e08-4690-8e38-4538b602260e - Disconnected
13:59:07.6100082 - ac120389-8e08-4690-8e38-4538b602260e - Transport.Dispose(ac120389-8e08-4690-8e38-4538b602260e)
13:59:07.6135102 - ac120389-8e08-4690-8e38-4538b602260e - Closed
Exception thrown: 'Microsoft.AspNet.SignalR.Client.HttpClientException' in mscorlib.ni.dll
And the angular client error says:
[21:52:32 GMT+0100 (Mitteleuropäische Zeit)] SignalR: Client subscribed to hub 'sensordatahub'.
jquery.signalR.min.js:8 [21:52:32 GMT+0100 (Mitteleuropäische Zeit)] SignalR: Negotiating with 'http://test.server.com//signalr/negotiate?clientProtocol=1.5&connectionData=%5B%7B%22name%22%3A%22sensordatahub%22%7D%5D'.
jquery.signalR.min.js:8 [21:52:32 GMT+0100 (Mitteleuropäische Zeit)] SignalR: webSockets transport starting.
jquery.signalR.min.js:8 [21:52:32 GMT+0100 (Mitteleuropäische Zeit)] SignalR: Connecting to websocket endpoint 'ws://test.server.com/signalr/connect?transport=webSockets&clientProtocol=1.5&connectionToken=AQAAANCMnd8BFdERjHoAwE%2FCl%2BsBAAAAVQGqCkfcnkONWeEawJYNqQAAAAACAAAAAAAQZgAAAAEAACAAAAC8DLAeriEnbunGPma3%2F%2FChRl1tm6XCfCHDLEEBfpjszgAAAAAOgAAAAAIAACAAAACANAtQqijBRvg4FloVq0JnylH9%2Bm6j5coY3Yr0yP60mzAAAAD4qw2VdYIQJ3CYQPcPbr2LhyfPhhJtPPgJ33FZuPLQh8owubvHYD5jhRsXdMxHfitAAAAAJX0cLVthvatbmOa%2BNbRSt%2B8CnVJ%2FQ9ks1x%2Bzlk2wA8iF6OVU03wXaNK17FXK2%2BlFmU6hIk8euqJVXeZMz7%2Bfnw%3D%3D&connectionData=%5B%7B%22name%22%3A%22sensordatahub%22%7D%5D&tid=4'.
jquery.signalR.min.js:8 WebSocket connection to 'ws://test.server.com/signalr/connect?transport=webSockets&clientProtocol=1.5&connectionToken=AQAAANCMnd8BFdERjHoAwE%2FCl%2BsBAAAAVQGqCkfcnkONWeEawJYNqQAAAAACAAAAAAAQZgAAAAEAACAAAAC8DLAeriEnbunGPma3%2F%2FChRl1tm6XCfCHDLEEBfpjszgAAAAAOgAAAAAIAACAAAACANAtQqijBRvg4FloVq0JnylH9%2Bm6j5coY3Yr0yP60mzAAAAD4qw2VdYIQJ3CYQPcPbr2LhyfPhhJtPPgJ33FZuPLQh8owubvHYD5jhRsXdMxHfitAAAAAJX0cLVthvatbmOa%2BNbRSt%2B8CnVJ%2FQ9ks1x%2Bzlk2wA8iF6OVU03wXaNK17FXK2%2BlFmU6hIk8euqJVXeZMz7%2Bfnw%3D%3D&connectionData=%5B%7B%22name%22%3A%22sensordatahub%22%7D%5D&tid=4' failed: Error during WebSocket handshake: Unexpected response code: 400
jquery.signalR.min.js:8 [21:52:32 GMT+0100 (Mitteleuropäische Zeit)] SignalR: Websocket closed.
jquery.signalR.min.js:8 [21:52:32 GMT+0100 (Mitteleuropäische Zeit)] SignalR: Closing the Websocket.
jquery.signalR.min.js:8 [21:52:32 GMT+0100 (Mitteleuropäische Zeit)] SignalR: webSockets transport failed to connect. Attempting to fall back.
jquery.signalR.min.js:8 [21:52:32 GMT+0100 (Mitteleuropäische Zeit)] SignalR: serverSentEvents transport starting.
jquery.signalR.min.js:8 [21:52:32 GMT+0100 (Mitteleuropäische Zeit)] SignalR: Attempting to connect to SSE endpoint 'http://test.server.com/signalr/connect?transport=serv…nw%3D%3D&connectionData=%5B%7B%22name%22%3A%22sensordatahub%22%7D%5D&tid=6'.
jquery.signalR.min.js:8 [21:52:37 GMT+0100 (Mitteleuropäische Zeit)] SignalR: serverSentEvents transport timed out when trying to connect.
jquery.signalR.min.js:8 [21:52:37 GMT+0100 (Mitteleuropäische Zeit)] SignalR: EventSource calling close().
jquery.signalR.min.js:8 [21:52:37 GMT+0100 (Mitteleuropäische Zeit)] SignalR: serverSentEvents transport failed to connect. Attempting to fall back.
jquery.signalR.min.js:8 [21:52:37 GMT+0100 (Mitteleuropäische Zeit)] SignalR: foreverFrame transport starting.
jquery.signalR.min.js:8 [21:52:37 GMT+0100 (Mitteleuropäische Zeit)] SignalR: Forever Frame is not supported by SignalR on browsers with SSE support.
jquery.signalR.min.js:8 [21:52:37 GMT+0100 (Mitteleuropäische Zeit)] SignalR: foreverFrame transport failed to connect. Attempting to fall back.
jquery.signalR.min.js:8 [21:52:37 GMT+0100 (Mitteleuropäische Zeit)] SignalR: longPolling transport starting.
jquery.signalR.min.js:8 [21:52:38 GMT+0100 (Mitteleuropäische Zeit)] SignalR: Opening long polling request to 'http://test.server.com/signalr/connect?transport=long…z7%2Bfnw%3D%3D&connectionData=%5B%7B%22name%22%3A%22sensordatahub%22%7D%5D'.
jquery.min.js:4 POST http://test.server.com/signalr/connect?transport=long…z7%2Bfnw%3D%3D&connectionData=%5B%7B%22name%22%3A%22sensordatahub%22%7D%5D 400 (Bad Request)l.cors.b.crossDomain.send # jquery.min.js:4n.extend.ajax # jquery.min.js:4r.transports._logic.ajax # jquery.signalR.min.js:8e # jquery.signalR.min.js:8(anonymous function) # jquery.signalR.min.js:8
jquery.signalR.min.js:8 [21:52:38 GMT+0100 (Mitteleuropäische Zeit)] SignalR: longPolling transport failed to connect. Attempting to fall back.
jquery.signalR.min.js:8 [21:52:38 GMT+0100 (Mitteleuropäische Zeit)] SignalR: Fallback transports exhausted.
signalRHubService.js:13 Could not Connect!
jquery.signalR.min.js:8 [21:52:38 GMT+0100 (Mitteleuropäische Zeit)] SignalR: Stopping connection.
jquery.signalR.min.js:8 [21:52:38 GMT+0100 (Mitteleuropäische Zeit)] SignalR: Fired ajax abort async = true.
jquery.signalR.min.js:8 [21:52:38 GMT+0100 (Mitteleuropäische Zeit)] SignalR: LongPolling failed to connect.
jquery.min.js:4 POST http://test.server.com//signalr/abort?transport=longP…z7%2Bfnw%3D%3D&connectionData=%5B%7B%22name%22%3A%22sensordatahub%22%7D%5D 400 (Bad Request)l.cors.b.crossDomain.send # jquery.min.js:4n.extend.ajax # jquery.min.js:4r.transports._logic.ajax # jquery.signalR.min.js:8r.transports._logic.ajaxAbort # jquery.signalR.min.js:8r.transports.longPolling.abort # jquery.signalR.min.js:8r.fn.r.stop # jquery.signalR.min.js:8a.state.r.connectionState.connecting.d # jquery.signalR.min.js:8v # jquery.signalR.min.js:8h.transportFailed # jquery.signalR.min.js:8(anonymous function) # jquery.signalR.min.js:8y # jquery.signalR.min.js:8s.pollXhr.i.ajax.error # jquery.signalR.min.js:8i # jquery.min.js:2j.fireWith # jquery.min.js:2z # jquery.min.js:4(anonymous function) # jquery.min.js:4
I'm getting failed: Error during WebSocket handshake: Unexpected response code: 400. Why can I connect on localhost, but not on cloud?

Without seeing more of your code, this is just a WAG, but...
Based on the fact that it was a 'Bad Request' error and the log says it timed out on all the transport types, my instincts are telling me that on your local machine,
when you configure the uri for the OWIN self host, you tell it to bind to localhost:80.
When the service fabric local cluster starts and runs the
Stateful/lessService (or I suppose you could do it with Actors) it
instantiates the OWIN self-host
OWIN binds to localhost:80 and requests to localhost:80 are correctly routed there
Warm fuzzies are had.
However, when moving the cluster up to Azure:
you want to change the OWIN uri address, because localhost is no longer appropriate,
so you chose 'test.server.com', or whatever it actually was.
Now though, the cluster isn't on a single machine, it's up in Azure
and whatever binding you want to use probably isn't valid.
Meaning, your OWIN host may be listening for 'test.server.com' requests, but none are coming because no DNS is pointing 'test.server.com' to the service fabric machine(s) hosting the service (which is hosting the OWIN self-host).
Some documentation I read noted that the service fabric framework has its own name servers which resolve the service fabric references to actual machine address, which is why you refer to service fabric services using the 'fabric:' protocol and let the routing magic happen behind the scenes. So the same limitation that means you can't directly expose an HTTP endpoint for a Service Fabric service without using an intermediary (see this MSDN article for details), is going to limit your ability to self host and bind to a uri that external clients can use.
This article talks about using OWIN to self-host Web API in an Azure Worker role, but the example is limited to using the local emulator and doesn't seem to address the fact that the ip address assigned to the endpoint could and would change in the cloud, making it hard to address reliably on the client.
If you were trying to move the SignalR hub to Service Fabric because you wanted to be able to take advantage of Service Fabric's scalability, check here. The currently recommended/supported path to scale out SignalR that looks like the best fit for what you've got there would be using Web Roles and Azure Service Bus as shown here.

Related

Query health check endpoints in ASP.NET

I implemented a health check endpoint following this doc. My ASP.NET application is dockerized and runs using docker-compose, with the port mapped/exposed.
Question: I am not sure how to query the health check endpoint from clients such as postman.
When I send a GET request to the /healthz endpoint as the following, postman throws the following error.
http://host.docker.internal:1200/healthz
Error: Client network socket disconnected before secure TLS connection was established
while I can see the following in the logs of the docker container.
[05:01:03 DBG] Connection id "0HMLSHSV1HRD2" accepted.
[05:01:03 DBG] Connection id "0HMLSHSV1HRD2" started.
[05:01:03 INF] Request starting HTTP/1.1 GET http://host.docker.internal:1200/healthz - -
[05:01:03 DBG] Wildcard detected, all requests with hosts will be allowed.
[05:01:03 VRB] All hosts are allowed.
[05:01:03 DBG] 1 candidate(s) found for the request path '/healthz'
[05:01:03 DBG] Request matched endpoint 'Health checks'
[05:01:03 DBG] Static files was skipped as the request already matched an endpoint.
[05:01:03 DBG] Https port '1200' loaded from configuration.
[05:01:03 DBG] Redirecting to 'https://host.docker.internal:1200/healthz'.
[05:01:03 DBG] Connection id "0HMLSHSV1HRD2" completed keep alive response.
[05:01:03 INF] Request finished HTTP/1.1 GET http://host.docker.internal:1200/healthz - - - 307 0 - 89.5220ms

How to use SignalR via Ngnix Reverse SSL Proxy

I'm trying to config a web api with SignalR enabled, so I can push real-time information to the clients via websockets. In front of the api I have a nginx reverse ssl proxy running in a docker container.
Clients can connect just fine via the reverse proxy when ssl is disabled in the nginx configuration:
server {
listen 55555;
# listen 55555 ssl;
ssl_certificate /config/keys/cert.crt;
ssl_certificate_key /config/keys/cert.key;
location / {
proxy_pass http://192.168.1.175:50000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
But when I configure the proxy to listen for ssl the clients can't seem to connect, or at least the client gets a "The server disconnected before the handshake could be started" IOException after what appears to be a time out.
WebAPI log:
info: Microsoft.AspNetCore.Hosting.Diagnostics[1]
Request starting HTTP/1.1 POST http://192.168.1.150/chatHub/negotiate?negotiateVersion=1 - 0
info: Microsoft.AspNetCore.Routing.EndpointMiddleware[0]
Executing endpoint '/chatHub/negotiate'
dbug: Microsoft.AspNetCore.Http.Connections.Internal.HttpConnectionManager[1]
New connection i-HjjQP9EsA_rBTX7vFs2Q created.
dbug: Microsoft.AspNetCore.Http.Connections.Internal.HttpConnectionDispatcher[10]
Sending negotiation response.
info: Microsoft.AspNetCore.Routing.EndpointMiddleware[1]
Executed endpoint '/chatHub/negotiate'
info: Microsoft.AspNetCore.Hosting.Diagnostics[2]
Request finished HTTP/1.1 POST http://192.168.1.150/chatHub/negotiate?negotiateVersion=1 - 0 - 200 316 application/json 117.3988ms
info: Microsoft.AspNetCore.Hosting.Diagnostics[1]
Request starting HTTP/1.1 POST http://192.168.1.150/chatHub/negotiate?negotiateVersion=1 - 0
info: Microsoft.AspNetCore.Routing.EndpointMiddleware[0]
Executing endpoint '/chatHub/negotiate'
dbug: Microsoft.AspNetCore.Http.Connections.Internal.HttpConnectionManager[1]
New connection K0y7OI3-3KvPIXWV92HEkA created.
dbug: Microsoft.AspNetCore.Http.Connections.Internal.HttpConnectionDispatcher[10]
Sending negotiation response.
info: Microsoft.AspNetCore.Routing.EndpointMiddleware[1]
Executed endpoint '/chatHub/negotiate'
info: Microsoft.AspNetCore.Hosting.Diagnostics[2]
Request finished HTTP/1.1 POST http://192.168.1.150/chatHub/negotiate?negotiateVersion=1 - 0 - 200 316 application/json 11.6330ms
info: Microsoft.AspNetCore.Hosting.Diagnostics[1]
Request starting HTTP/1.1 GET http://192.168.1.150/chatHub?id=zdDUpBZ-RsnQgEZsJ9Sctg - -
info: Microsoft.AspNetCore.Routing.EndpointMiddleware[0]
Executing endpoint '/chatHub'
dbug: Microsoft.AspNetCore.Http.Connections.Internal.HttpConnectionDispatcher[4]
Establishing new connection.
dbug: Microsoft.AspNetCore.SignalR.HubConnectionHandler[5]
OnConnectedAsync started.
dbug: Microsoft.AspNetCore.SignalR.HubConnectionContext[2]
Handshake was canceled.
dbug: Microsoft.AspNetCore.Http.Connections.Internal.HttpConnectionManager[2]
Removing connection zdDUpBZ-RsnQgEZsJ9Sctg from the list of connections.
info: Microsoft.AspNetCore.Routing.EndpointMiddleware[1]
Executed endpoint '/chatHub'
info: Microsoft.AspNetCore.Hosting.Diagnostics[2]
Request finished HTTP/1.1 GET http://192.168.1.150/chatHub?id=zdDUpBZ-RsnQgEZsJ9Sctg - - - 200 - text/event-stream 60079.4344ms
I've tried including the following in the WebApplication settings:
builder.Services.Configure<ForwardedHeadersOptions>(options =>
{
options.KnownProxies.Add(IPAddress.Parse("192.168.1.150")); // Proxy Server IP
});
app.UseForwardedHeaders(new ForwardedHeadersOptions
{
ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto | ForwardedHeaders.XForwardedHost
});
But as far as I can tell, it doesn't really make a difference.
I'm unsure whether this is a nginx reverse proxy/sll or a Webpi/SignalR issue. Any ideas? :)

System.IO.IOException: The handshake failed due to an unexpected packet format

I'm trying to connect to a non-secure web socket server through WS, although when setting up a proxy with nginx I receive (on the WS server):
The handshake failed due to an unexpected packet format.
This is handled as an IOException, and crashes the entire server.
stacktrace
Here is my nginx configuration:
server {
listen 80;
listen [::]:80;
server_name ws.tunnel.cf;
return 302 https://$server_name$request_uri;
}
server {
# SSL configuration
listen 443 ssl;
listen [::]:443 ssl;
ssl_certificate /etc/ssl/certs/cert.pem;
ssl_certificate_key /etc/ssl/private/key.pem;
server_name ws.tunnel.cf;
location / {
proxy_pass http://213.43.156.21:8000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
}
How exactly can I connect to my non secure web socket server, without making it WSS?
I am using Fleck as a package for the server.
Code for connecting:
const socket = new WebSocket('wss://ws.tunnel.cf');
socket.addEventListener('open', function (event) {
console.log('WS:open');
});

kestrel + nginx intermittent 502

I have an ASP.NET core 1.0 app running on ubuntu 16.04 behind nginx/1.10.0. However, I notice that intermittently nginx throws the following error (in nginx error-log)
2017/06/08 05:19:19 [error] 11572#11572: *119049 upstream prematurely closed connection while reading response header from upstream, client: <ipaddress>, server: <servername>, request: "POST /<uri> HTTP/1.1", upstream: "http://127.0.0.1:5000/<uri>", host: "<servername>"
which results in a 502 Bad Gateway to the client although the request completes successfully in the application
2017-06-08 05:19:14.399 [DBG] Executed action method "<Controller.Action>", returned result "Microsoft.AspNetCore.Mvc.CreatedAtRouteResult
Could this be an nginx configuration issue or ASP.NET/Kestrel issue? Can someone give me hints to debug this?
Further notes:
I also see the following in the application log just after request completion
2017-06-08 05:19:14.399 [DBG] Executed action method "<Controller.Action>", returned result "Microsoft.AspNetCore.Mvc.CreatedAtRouteResult
2017-06-08 05:19:18.632 [DBG] Some connections failed to close gracefully during server shutdown.
2017-06-08 05:19:22.402 [DBG] Hosting starting
2017-06-08 05:19:22.689 [DBG] Hosting started
and the nginx error is just around the same time 2017/06/08 05:19:19
Also, normally in the logs I see messages around Executing ObjectResult and Executed time etc. which I don't see with the above request
2017-06-08 00:10:14.391 [DBG] Selected output formatter '"Microsoft.AspNetCore.Mvc.Formatters.JsonOutputFormatter"' and content type '"application/json"' to write the response.
2017-06-08 00:10:14.391 [INF] Executing ObjectResult, writing value "Microsoft.AspNetCore.Mvc.ControllerContext".
2017-06-08 00:10:14.504 [INF] Executed action "<Controller.Action>" in 1875.3845ms

WebSocket sending an HTTP header on connection - how to prevent?

When I open a web socket to my server - it looks like the client is automatically sending an HTTP request as part of the first payload. How can I prevent this?
That is the nature of the web socket protocol. It starts with a handshake done over simple HTTP
GET /mychat HTTP/1.1
Host: server.example.com
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: x3JJHMbDL1EzLkh9GBhXDw==
Sec-WebSocket-Protocol: chat
Sec-WebSocket-Version: 13
Origin: http://example.com
More: http://en.wikipedia.org/wiki/WebSocket#WebSocket_protocol_handshake
You cannot create a websocket without this handshake.

Categories

Resources