• Please be aware: Kaspersky Anti-Virus has been deprecated
    With the upgrade to Plesk Obsidian 18.0.64, "Kaspersky Anti-Virus for Servers" will be automatically removed from the servers it is installed on. We recommend that you migrate to Sophos Anti-Virus for Servers.
  • The Horde webmail has been deprecated. Its complete removal is scheduled for April 2025. For details and recommended actions, see the Feature and Deprecation Plan.

Resolved PHP Websockets

dataconnect

New Pleskian
Server operating system version
Almalinux 9.2
Plesk version and microupdate number
18.0.61
We are operating 8 servers with Plesk, hosting several Single Page Applications (SPAs) built with PHP and JavaScript, using a custom JS router. These applications handle daily tasks for our customers.

Several customers have requested a security feature to ensure a user is not logged in on multiple devices simultaneously. If a user logs in on a new device, they should be logged out from any previous device.

(YES, we can build and have built Next.js apps with Express and Socket.io, but these next.js does not work on Plesk out of the box)

When a user reloads on another device, it checks if the user is still logged in and redirects if not. However, this is based on user input and does not meet the requirement for real-time checks.

We are using PHP socket server (Ratchet) to handle login checks and potentially future features like popup messages and live chat.
While everything works perfectly in our local development environment, we encounter issues in our production environment. The WebSocket connection does not start.
We tried disabling Nginx proxy mode as suggested in some posts, but it still doesn't work.

We are getting a response so we know that it tries to start.

WebSocket URL: wss://domain.com:8081 socket.js:14:9Object { ws: WebSocket, login: login(loginid, sessionid) }login: function login(loginid, sessionid)ws: WebSocket { url: "wss://domain.com:8081/", readyState: 0, bufferedAmount: 0, … }<prototype>: Object { … }

WebSocket connection closed

close { target: WebSocket, isTrusted: true, wasClean: false, code: 1006, reason: "", srcElement: WebSocket, currentTarget: WebSocket, eventPhase: 2, bubbles: false, cancelable: false, … }

does someone have a idea where to look?
 
close { target: WebSocket, isTrusted: true, wasClean: false, code: 1006, reason: "", srcElement: WebSocket, currentTarget: WebSocket, eventPhase: 2, bubbles: false, cancelable: false, … }
That's tricky, because error code 1006 is rather generic. Are there any errors logged in the domains error logs?
 
The socket server is working now that the OpenSSL library is installed. To clarify, I can start the server, and it confirms that it is running on port 8080 (as seen in the server console) and i have a PID. However, my SPA still refuses to connect to it.

Initially, I was running the server on version 8.2 and the SPA on version 8.3. Suspecting a version mismatch, I downgraded the SPA to 8.2, but the issue persists. The port is definitely open, as I receive no response if it wasn't.

(The server.php is located in my domain)

[root@app01 shared]# /opt/plesk/php/8.2/bin/php server.php
[2024-06-24 10:14:06] WebSocket server started on port 8080

Powershell from my Windows computer.
Test-NetConnection -ComputerName domain.com -Port 8080

ComputerName : domain.com
RemoteAddress : ##.##.##.216
RemotePort : 8080
InterfaceAlias : Ethernet
SourceAddress : 192.168.1.128
TcpTestSucceeded : True

So I know that its running and the port is open.
I have no clue what to think of next to get it working.
 
I've searched through the error logs but haven't found anything relevant (at least nothing that stands out to me). I've tried everything I can think of. The connection via JavaScript on my SPA is client-side, so when it can't connect, it just fails without producing a server error. However, it is indeed connecting:

[2024-06-25 08:16:56] WebSocket server started on port 8080
[2024-06-25 08:24:21] New connection! (125)

So, I know that part is working.
The next thing I did was to set up Apache and Nginx directives. I also tried toggling Proxy mode on and off, but no luck, and no errors.

Apache
ProxyRequests OffProxyPass /ws ws://127.0.0.1:8080/ws
ProxyPassReverse /ws ws://127.0.0.1:8080/ws

Nginx
location /ws {
proxy_pass http://127.0.0.1:8080
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Host $host;
proxy_cache_bypass $http_upgrade;
}

Still no results or errors. I also checked Apache to ensure that the proxy modules are included, and they are (in 00-proxy.conf):

LoadModule proxy_module modules/mod_proxy.so
LoadModule proxy_wstunnel_module modules/mod_proxy_wstunnel.so

It's not an issue with my JavaScript on the SPA, because when I test with PowerShell on Windows, it does the exact same thing. It connects but I get no response back. The only 'error' is from my clientside as a response but as previous mentioned its connection. so when its connecting it uses wss://domain.com:8080/ws

Firefox kan geen verbinding maken met de server op wss://domain.com:8080/ws. socket.js:15:12

WebSocket error:

error { target: WebSocket, isTrusted: true, srcElement: WebSocket, currentTarget: WebSocket, eventPhase: 2, bubbles: false, cancelable: false, returnValue: true, defaultPrevented: false, composed: false, … }
bubbles: false
cancelBubble: false
cancelable: false
composed: false
currentTarget: WebSocket { url: "wss://domain.com:8080/ws", readyState: 3, bufferedAmount: 0, … }
defaultPrevented: false
eventPhase: 2
explicitOriginalTarget: WebSocket { url: "wss://domain.com:8080/ws", readyState: 3, bufferedAmount: 0, … }
isTrusted: true
originalTarget: WebSocket { url: "wss://domain.com:8080/ws", readyState: 3, bufferedAmount: 0, … }
returnValue: true
srcElement: WebSocket { url: "wss://domain.com:8080/ws", readyState: 3, bufferedAmount: 0, … }

target: WebSocket { url: "wss://domain.com:8080/ws", readyState: 3, bufferedAmount: 0, … }
timeStamp: 20468
type: "error"

<get isTrusted()>: function isTrusted()
<prototype>: EventPrototype { composedPath: composedPath(), stopPropagation: stopPropagation(), stopImmediatePropagation: stopImmediatePropagation(), … }

The only thing I can think of is that it might still be related to the reverse proxy and /ws as a response. But I'm out of ideas.
Any suggestions or insights would be greatly appreciated.
 
I am not an expert on the subject of WebSockets. But I did just ran a couple of tests with Ratchet. For me, on my test setup, I am only able to successfully establish WebSocket connections if I don't specify the port on the script. Connections get proxied to the right port by the Nginx directives.

So maybe that's something you can try?
 
WebSocket connection established

Thank you so much! This support far exceeds my expectations.
You've got my vote for Community Manager of the Year (even if it's only halfway through 2024 yet)! ;) Pure GOLD!
 
WebSocket connection established

Thank you so much! This support far exceeds my expectations.
You've got my vote for Community Manager of the Year (even if it's only halfway through 2024 yet)! ;) Pure GOLD!
Hello,

Can you share the config that worked for you ? Thanks
 
Back
Top