1

I'm using a Ubuntu server on DigitalOcean to host an Nginx web server and a Node app that runs a WebSocket server. When attempting to connect to the IP of the server, I get the following message in the console:

WebSocket connection to 'ws://<server's public IP>' failed: Error during WebSocket handshake: Unexpected response code: 200

All I did to set up Nginx was to follow this guide, which simply tells you to install Nginx and adjust the UFW firewall. I didn't set up server blocks in Step 4, and I haven't touched any other config files.

After that, I put my index.html and client.js files in the /var/www/html directory to be served by Nginx.

index.html is a very simple HTML page that runs client.js. That JS file looks like this:

const ws = new WebSocket('ws://<public IP, same as above>:80');

ws.addEventListener('open', () => {
    const json = { message: 'hello from client!' };
    const jsonString = JSON.stringify(json);
    ws.send(jsonString);
});

ws.addEventListener('message', event => {
    const data = JSON.parse(event.data);
    console.log(data);
});

The server side Node app is websocket.js, and it looks like this:

const buffer = require('buffer');
const http = require('http').createServer();
const ws = require('ws');
const wsServer = new ws.Server({ server: http });

wsServer.on('connection', (socket) => {
    socket.on('message', (msg) => {
        console.log('received: ' + msg);
        socket.send(Buffer.from('hello from the server!'));
    });

    const json = { message: 'hello from server!' };
    const jsonString = JSON.stringify(json);
    socket.send(Buffer.from(jsonString));
});

http.listen(8080, () => console.log('listening on 8080'));

This file was placed at /root along with node_modules, package.json, and package-lock.json. Serving it alongside the client side code at /var/www/html didn't help. Of course, it was also running thanks to PM2, and I have also tried running without PM2 which made no difference.

Any help is appreciated, please let me know if there's any information I might have missed.

1 Answer 1

3

Turns out there are some extra steps you need to take in order to get Nginx and Node.js to play nicely.

I went to the /etc/nginx/sites-available/default and updated this block:

location / {
    try_files $uri $uri/ =404;
}

to this block:

location / {
    proxy_pass http://localhost:8080;  # change to your port if needed
    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;
    try_files $uri $uri/ =404;
}

And then updated my Node app to serve files through Express with app.use(express.static('/var/www/html'));.

Here are a couple of links that helped lead me to the right answer:

Node.js + Nginx - What now?

https://www.digitalocean.com/community/questions/how-to-run-node-js-server-with-nginx

And an extra link I found which tells you more about the Nginx directives used:

http://nginx.org/en/docs/http/ngx_http_proxy_module.html

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.