nginx proxying websockets, must be missing something

Posted by CodeMonkey on Server Fault See other posts from Server Fault or by CodeMonkey
Published on 2013-11-08T14:25:11Z Indexed on 2013/11/08 15:59 UTC
Read the original article Hit count: 1011

Filed under:
|
|

I have a basic chat app written in node.js using express and socket.io; it works fine when connecting directly to node on port 3000

But doesn't work when I try to use nginx v1.4.2 as a proxy.

I start off using the connection map

map $http_upgrade $connection_upgrade {
    default upgrade;
    ''      close;
}

Then add the locations

location /socket.io/ {
   proxy_pass  http://node;
   proxy_redirect off;
   proxy_http_version 1.1;
   proxy_set_header Host $http_host;
   proxy_set_header X-Forwarded-For $remote_addr;
   proxy_set_header X-Request-Id $txid;
   proxy_set_header X-Session-Id $uid_set+$uid_got;
   proxy_set_header Upgrade $http_upgrade;
   proxy_set_header Connection $connection_upgrade;
   proxy_buffering off;

   proxy_read_timeout 86400;
    keepalive_timeout 90;

    proxy_cache off;

    access_log /var/log/nginx/webservice.access.log;
    error_log /var/log/nginx/webservice.error.log;
}

location /web-service/ {
   proxy_pass  http://node;
   proxy_redirect off;
   proxy_http_version 1.1;
   proxy_set_header Host $http_host;
   proxy_set_header X-Forwarded-For $remote_addr;
   proxy_set_header X-Request-Id $txid;
   proxy_set_header X-Session-Id $uid_set+$uid_got;
   proxy_set_header Upgrade $http_upgrade;
   proxy_set_header Connection $connection_upgrade;
   proxy_buffering off;

   proxy_read_timeout 86400;

    keepalive_timeout 90;

    access_log /var/log/nginx/webservice.access.log;
    error_log /var/log/nginx/webservice.error.log;

   rewrite /web-service/(.*) /$1 break;

   proxy_cache off;
}

These are built up using all of the tips to get it working that I could find. The error log does not show any errors. (except when I stop node to test the error logging is working)

When through nginx I do see a websocket connection in the dev tools, with the status of 101; but the frames tab under the resuects is empty. The only differnece I can see in the response headers is a case difference - "upgrade" vs "Upgrade" - through nginx :

Connection:upgrade
Date:Fri, 08 Nov 2013 11:49:25 GMT
Sec-WebSocket-Accept:LGB+iEBb8Ql9zYfqNfuuXzdzjgg=
Server:nginx/1.4.2
Upgrade:websocket

direct from node

Connection:Upgrade
Sec-WebSocket-Accept:8nwPpvg+4wKMOyQBEvxWXutd8YY=
Upgrade:websocket

output from node (when used through nginx)

debug - served static content /socket.io.js
debug - client authorized
info  - handshake authorized iaej2VQlsbLFIhachyb1
debug - setting request GET /socket.io/1/websocket/iaej2VQlsbLFIhachyb1
debug - set heartbeat interval for client iaej2VQlsbLFIhachyb1
debug - client authorized for
debug - websocket writing 1::
debug - websocket writing 5:::{"name":"message","args":[{"message":"welcome to the chat"}]}
debug - clearing poll timeout
debug - jsonppolling writing io.j[0]("8::");
debug - set close timeout for client 7My3F4CuvZC0I4Olhybz
debug - jsonppolling closed due to exceeded duration
debug - clearing poll timeout
debug - jsonppolling writing io.j[0]("8::");
debug - set close timeout for client AkCYl0nWNZAHeyUihyb0
debug - jsonppolling closed due to exceeded duration
debug - setting request GET /socket.io/1/xhr-polling/iaej2VQlsbLFIhachyb1?t=1383911206158
debug - setting poll timeout
debug - discarding transport
debug - cleared heartbeat interval for client iaej2VQlsbLFIhachyb1
debug - setting request GET /socket.io/1/jsonp-polling/iaej2VQlsbLFIhachyb1?t=1383911216160&i=0
debug - setting poll timeout
debug - discarding transport
debug - clearing poll timeout
debug - clearing poll timeout
debug - jsonppolling writing io.j[0]("8::");
debug - set close timeout for client iaej2VQlsbLFIhachyb1
debug - jsonppolling closed due to exceeded duration
debug - setting request GET /socket.io/1/jsonp-polling/iaej2VQlsbLFIhachyb1?t=1383911236429&i=0
debug - setting poll timeout
debug - discarding transport
debug - cleared close timeout for client iaej2VQlsbLFIhachyb1

when direct to node, the client does not start polling.

The normal http stuff node outputs works fine with nginx.

Clearly something I am not seeing, but I am stuck, thanks :)

© Server Fault or respective owner

Related posts about nginx

Related posts about node.js