nginx as webserver incl. socket.io and node.js / ws:// 400 Bad Request

nginx, node.js, socket.io, sockets, web-services

Solution

Nginx(nginx version: nginx/1.4.6) Change:-

server {
        listen   80;
        server_name 255717070.com;
        root /var/www/stack/25571070;
        index  index.html index.htm;

        location / {
        }

        location ^~ /socket {
           rewrite  ^/socket/(.*)  /$1 break; #used to send request to base url
           proxy_pass http://127.0.0.1:3000;
           proxy_redirect off;
           proxy_pass_request_headers on;
           proxy_set_header X-Real-IP $remote_addr;
           proxy_set_header Host $http_host;
           proxy_set_header X-NginX-Proxy true;
           proxy_set_header X-Forwarded-Host $host;
           proxy_set_header X-Forwarded-Server $host;
           proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
           proxy_http_version 1.1;
           proxy_set_header Upgrade $http_upgrade;
           proxy_set_header Connection "upgrade";
           proxy_set_header Host $host;

        }

}

Note: You need to change `location ~ ^/socket` to `location ^~ /socket`

Node Changes:

app.js:

app.enable('trust proxy');
app.set('port', process.env.PORT || 3000);
var server = app.listen(app.get('port'), function() {
     debug('Express server listening on port ' + server.address().port);
});


var sockets = require('socket.io')({
  'transports': ['websocket', 'flashsocket','htmlfile','xhr-polling','jsonp-polling']
});

var io = sockets.listen(server,{ resource: '/socket.io/','sync disconnect on unload':true });

io.sockets.on('connection', function (socket) {  
  setInterval(function() {socket.emit('news', { hello: 'hello world' })}, 1000);
});

index.ejs:

<!DOCTYPE html>
<html>
  <head>
    <title><%= title %></title>
    <link rel='stylesheet' href='/socket/stylesheets/style.css' />
  </head>
  <body>
    <h1><%= title %></h1>
    <p>Welcome to <%= title %></p>
    <div id="divID">

    </div>
    <script src="http://www.25571070.com/socket/socket.io/socket.io.js"></script>
        <script>
            var socket = io.connect('ws://25571070.com');
            //var socket = io.connect('http://www.25571070.com');
            var i = 0;
            socket.on('news', function(data) {
                var div = document.getElementById('divID');
                i = i + 1;
                div.innerHTML = div.innerHTML + '<p>'+ data.hello+'('+i+')'+'</p>';
                console.log(data);
            });
        </script>
  </body>
</html>

package.json:

{
  "name": "25571070",
  "version": "0.0.0",
  "private": true,
  "scripts": {
    "start": "node ./bin/www"
  },
  "dependencies": {
    "body-parser": "~1.6.6",
    "cookie-parser": "~1.3.2",
    "debug": "~1.0.4",
    "ejs": "~0.8.5",
    "express": "~4.8.6",
    "moment": "^2.8.2",
    "morgan": "^1.2.3",
    "serve-favicon": "^2.0.1",
    "socket.io": "^1.0.6",
    "stylus": "0.42.3"
  }
}

Firefox Response:

Chrome Response:

FYI. I have used below version:

- "node": "v0.10.31"

- "ejs": "~0.8.5"

- "express": "~4.8.6",

- "socket.io": "^1.0.6"

- "nginx": "1.4.6"

For Quick Start With node.js go to node.js-socket.io-express-ngnix-starter

Problem

i've got this error requests. The last sentence in german means "Firefox cant connect to the server which is located in ws://.......". The server wouldnt be the problem i think. Because that here is the nginx configuration, because i think there is the problem! ``` server { server_name example.org; listen 80 default_server; root /var/www/web; location / # for symfony2 { try_files $uri @rewriteapp; } location @rewriteapp # for symfony2 { rewrite ^(.*)$ /app.php/$1 last; } location ~ ^/app\.php(/|$) { fastcgi_pass unix:/var/run/php5-fpm.sock; fastcgi_split_path_info ^(.+\.php)(/.*)$; include fastcgi_params; fastcgi_param HTTPS off; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; } location ~ ^/socket { proxy_pass http://127.0.0.1:8080; proxy_redirect off; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; proxy_set_header Host $http_host; } access_log /var/log/nginx/access.log; error_log /var/log/nginx/error.log; } ``` nginx version: nginx/1.4.7 app.js (thats the server!) ``` var express = require('express'), io = require('socket.io').listen(server), server = require('http').createServer(app), bodyParser = require('body-parser'); var app = express(); server.listen(8080); app.use(bodyParser.json()); app.post('/', function(request, response) { response.send('OK'); io.emit('MessageForAll', request.body); }); io.on('connection', function (socket){}); console.log('Server running on port 8080.'); ```

Original source