Valdimir
Valdimir

Reputation: 11

Keep failing to create and connect to a websocket server on Ubuntu server

I am running the following:

Plesk PLSK.10247462.0001 on Ubuntu 22.04.2 LTS

I am using cloudflare as the DNS server and pointing the a record (proxied) to my ubuntu server

I have a domain there and running a codeigniter 4 app which works perfectly. Plesk is managing my firewall and I have Allow incoming from all on port 8080/tcp

I have tried many ways to run a websocket server including using ratchet on codeigniter and then using php server.php in about 15 different ways but the connections always fails. I have seen the following errors:

WebSocket connection to 'ws://localhost:8080/' failed: ERR_SSL_PROTOCOL_ERROR and others but I have forgotten them

I have tried using wss instead of ws and tried changing the port

This is my javascript code which generally stays the same with any method:

const webSocket = new WebSocket('ws://localhost:8080');

    webSocket.addEventListener('open', (event) => {
      console.log('WebSocket connection opened.');
      webSocket.send('Hello, server!');
    });

    webSocket.addEventListener('message', (event) => {
      console.log('Received message: ' + event.data);
    });

    webSocket.addEventListener('close', (event) => {
      console.log('WebSocket connection closed.');
    });

My latest attempt was to run the server using node.js and express ws the steps i took was as follows:

1: Created folder in /var/www/domain called webs 2: Initialized npm and ran npm install express express-ws
3: Created a server.js file with this content:

const express = require('express');
const expressWs = require('express-ws');

const app = express();
expressWs(app);

app.ws('/', (ws, req) => {
  console.log('WebSocket connection opened.');
  ws.send('Hello, client!');
  ws.on('message', (message) => {
    console.log('Received message: ' + message);
  });
  ws.on('close', () => {
    console.log('WebSocket connection closed.');
  });
});

app.listen(8080, () => {
  console.log('WebSocket server listening on port 8080.');
});

4: run the server by executing this command node server.js

I get the output "WebSocket server listening on port 7777." and I see the port 8080 is suddenly open but at the moment getting the following error "WebSocket connection to 'ws://localhost:8080/' failed: "

I think I am missing something fundamental since I have really tried over 15 methods some taking 20 minutes to setup. Sometimes the port stays closed even though I can see a process using the port using lsof -i :8080 and sometimes the port opens but the connection is never successful. I have also tried using the public IP and 1270.0.0.1 but to no avail. Is there something I am missing here?

I understand I am running the websocket server on the same server I am using for plesk, also, I'm not sure how I would get wss working, do I need a self-singed certificate? Any advice to set it up differently will be appreciated.

Thanks

Upvotes: 0

Views: 2434

Answers (1)

Valdimir
Valdimir

Reputation: 11

Please anyone correct me if I am wrong on anything

GETTING WEBSOCKET SERVER WORKING WITH PLESK

After days of debugging and very little documentation I have got it working and the root issue is that I am using plesk which by default uses APACHE

Because I am running a codeigniter app which ordinarily works well with apache because it heavily relies on .htaccess I can't simply switch to nginx as it won't work at all.

What I did was as follows:

  1. Created a subdomain (probably would work also with a separate domain)
  2. Turned off proxy mode (go to Apache & nginx Settings and uncheck 'proxy mode') - save this before continuing otherwise you will get an error on the next step
  3. Added the code at the bottom of this post to the 'Additional nginx directives'

It is important to know that cross origin should be allowed in both domains, you can see I added it to nginx directives for the subdomain, and for the main domain I added it to 'Additional directives for HTTPS' by pasting this: Header set Access-Control-Allow-Origin “https://SUB.MAINDOMAIN.COM”

The reason this is needed to be setup like this is because websockets use the hop-to-hop header for sending http requests which cannot be proxied with apache as they will be lost, so it needs to be through nginx and manually setting the proxy

Code for Additional nginx directives

location / {
proxy_pass http://127.0.0.1:3000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
add_header 'Access-Control-Allow-Origin' 'https://MAINDOMAIN.COM';
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range';
add_header 'Access-Control-Expose-Headers' 'Content-Length,Content-Range';
}

Note I am using port 3000, you can use the default (8080) or anything else, also it is important that you assign a certificate to the subdomain as well as the main domain so you don't get an SSL error, then use wss://sub.maindomain.com (do not put in the port) to connect to the server

Upvotes: 0

Related Questions