Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

SignalR in ASP.NET Core behind Nginx

Tags:

I have a server with ubuntu 16.04, kestrel and nginx as a proxy server that redirects to localhost where my app is. And my app is on Asp.Net Core 2. I'm trying to add push notifications and using SignalR core. On localhost everything is working well, and on a free hosting with iis and windows as well. But when I deploy my app on the linux server I have an error:

signalr-clientES5-1.0.0-alpha2-final.min.js?v=kyX7znyB8Ce8zvId4sE1UkSsjqo9gtcsZb9yeE7Ha10:1 WebSocket connection to 'ws://devportal.vrweartek.com/chat?id=210fc7b3-e880-4d0e-b2d1-a37a9a982c33' failed: Error during WebSocket handshake: Unexpected response code: 204

But this error occurs only if I request my site from different machine via my site name. And when I request the site from the server via localhost:port everything is fine. So I think there is a problem in nginx. I read that I need to configure it for working with websockets which are used in signalr for establishing connection but I wasn't succeed. May be there is just some dumb mistake?

enter image description here

like image 925
Artyom Avatar asked Jan 17 '18 11:01

Artyom


People also ask

Does SignalR require sticky session?

Sticky sessions, also known as client affinity, is not required, because clients are immediately redirected to the Azure SignalR Service when they connect.

What is the difference between SignalR and WebSockets?

WebSockets is actually the underlying transport that SignalR uses, at least most of the time. SignalR has the ability to fall back to other ways of transporting messages, such as long-polling over HTTP. This is useful in situations where you don't have WebSockets support.

Does SignalR keep connection alive?

You can handle this event if you want your application to take some action when a transport connection is lost. The default keepalive timeout period is currently 20 seconds. If your client code tries to call a Hub method while SignalR is in reconnecting mode, SignalR will try to send the command.


2 Answers

I was able to solve this by using $http_connection instead of keep-alive or upgrade

server {   server_name example.com;    location / {     proxy_pass http://localhost:5000;     proxy_http_version 1.1;     proxy_set_header Upgrade $http_upgrade;     proxy_set_header Connection $http_connection;     proxy_set_header Host $host;     proxy_cache_bypass $http_upgrade;   } } 

I did this because SignalR was also trying to use POST and GET requests to my hubs, so doing just an Upgrade to the connection in a separate server configuration wasn't enough.

like image 175
Raen Herron Avatar answered Sep 17 '22 13:09

Raen Herron


The problem is the nginx configuration file. If you are using the default settings of the ASP.NET Core deployment guide then the problem is the one of the proxy headers. WebSocket requires Connection header as "upgrade".

You have to set a new path for SignalR Hub on nginx configuration file.

such as

location /api/chat {     proxy_pass http://localhost:5000;     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; } 

You can read my full blog post

https://medium.com/@alm.ozdmr/deployment-of-signalr-with-nginx-daf392cf2b93

like image 29
alim Avatar answered Sep 21 '22 13:09

alim