I have built a chat app that uses Ratchet as the websocket library which I want to host online. But before that, I want to test the websocket connection online first so that I can confirm everything is working well before hosting the actual application. For this, I have downloaded two files from Github which is a simple PHP websocket script. One is index.php for the client side browser connection and one is socket.php which runs the server and connects in the terminal. This both scripts run well in the Xampp environment on my PC. I just have to do php socket.php and the script runs with ease. However, same method is not working on the VPS when I try it using Putty (SSH Connection). The server is Nginx and VPS control panel is CloudPanel. The two files are uploaded are:
index.php
<!DOCTYPE html>
<html>
<body>
<div id="root"></div>
<script>
var host = 'wss://mysite.app:9000/wsapp/';
var socket = new WebSocket(host);
socket.onmessage = function(e) {
document.getElementById('root').innerHTML = e.data;
};
</script>
</body>
</html>
socket.php
$address = 'mysite.app'; // localhost on Xampp and it works well there
$port = 9000;
// Create WebSocket.
$server = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
socket_set_option($server, SOL_SOCKET, SO_REUSEADDR, 1);
socket_bind($server, $address, $port);
socket_listen($server);
$client = socket_accept($server);
echo "Socket Accepted";
// Send WebSocket handshake headers.
$request = socket_read($client, 5000);
preg_match('#Sec-WebSocket-Key: (.*)\r\n#', $request, $matches);
$key = base64_encode(pack(
'H*',
sha1($matches[1] . '258EAFA5-E914-47DA-95CA-C5AB0DC85B11')
));
$headers = "HTTP/1.1 101 Switching Protocols\r\n";
$headers .= "Upgrade: websocket\r\n";
$headers .= "Connection: Upgrade\r\n";
$headers .= "Sec-WebSocket-Version: 13\r\n";
$headers .= "Sec-WebSocket-Accept: $key\r\n\r\n";
socket_write($client, $headers, strlen($headers));
echo "Connection Established!";
// Send messages into WebSocket in a loop.
while (true) {
sleep(1);
$content = 'Now: ' . time();
$response = chr(129) . chr(strlen($content)) . $content;
socket_write($client, $response);
}
When I execute php socket.php in the command line using SSH (putty), the line echo "Socket Accepted"; is never executed. Which means the socket_accept code is not getting executed here. I have been through several articles and most talk about making changes to the Nginx.conf file. However, I am not sure if just making that change will be enough because it can be due to blocked port or something else. Which I don't know how to open or debug. For reference, the code of Nginx.conf is given here:
server {
listen 80;
listen [::]:80;
listen 443 ssl http2;
listen [::]:443 ssl http2;
{{ssl_certificate_key}}
{{ssl_certificate}}
server_name mysite.app;
return 301 https://www.mysite.app$request_uri;
}
server {
listen 80;
listen [::]:80;
listen 443 ssl http2;
listen [::]:443 ssl http2;
{{ssl_certificate_key}}
{{ssl_certificate}}
server_name www.mysite.app www1.mysite.app;
{{root}}
{{nginx_access_log}}
{{nginx_error_log}}
if ($scheme != "https") {
rewrite ^ https://$host$uri permanent;
}
location ~ /.well-known {
auth_basic off;
allow all;
}
{{settings}}
location / {
{{varnish_proxy_pass}}
proxy_set_header Host $http_host;
proxy_set_header X-Forwarded-Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_hide_header X-Varnish;
proxy_redirect off;
proxy_max_temp_file_size 0;
proxy_connect_timeout 720;
proxy_send_timeout 720;
proxy_read_timeout 720;
proxy_buffer_size 128k;
proxy_buffers 4 256k;
proxy_busy_buffers_size 256k;
proxy_temp_file_write_size 256k;
}
location /wsapp/ {
proxy_pass http://www.mysite.app/socket.php;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
proxy_set_header Host $host;
}
location ~* ^.+\.(css|js|jpg|jpeg|gif|png|ico|gz|svg|svgz|ttf|otf|woff|woff2|eot|mp4|ogg|ogv|webm|webp|zip|swf|map)$ {
add_header Access-Control-Allow-Origin "*";
expires max;
access_log off;
}
if (-f $request_filename) {
break;
}
}
server {
listen 8080;
listen [::]:8080;
server_name www.mysite.app www1.mysite.app;
{{root}}
try_files $uri $uri/ /index.php?$args;
index index.php index.html;
location ~ \.php$ {
include fastcgi_params;
fastcgi_intercept_errors on;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
try_files $uri =404;
fastcgi_read_timeout 3600;
fastcgi_send_timeout 3600;
fastcgi_param HTTPS "on";
fastcgi_param SERVER_PORT 443;
fastcgi_pass 127.0.0.1:{{php_fpm_port}};
fastcgi_param PHP_VALUE "{{php_settings}}";
}
if (-f $request_filename) {
break;
}
}
I have added this block in the config file above:
location /wsapp/ {
proxy_pass http://www.mysite.app/socket.php;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
proxy_set_header Host $host;
}
Then, I restarted the Nginx server and in the terminal proceeded to the root folder of the website and tried running again php socket.php or php -q socket.php. However, it still doesn't work. The function socket_accept is still never executed. In the browser also, I always get Firefox can’t establish a connection to the server at wss://mysite.app:9000/wsapp/.
And lastly, my OS is Ubuntu 22.04. Please let me know if anymore info is needed to diagnose and I shall add it.
UPDATE
I want to add this information from terminal that I get by running command sudo ufw numbered. These are the ports allowed in firewall.
To Action From
-- ------ ----
80/tcp ALLOW Anywhere
443/tcp ALLOW Anywhere
8443/tcp ALLOW Anywhere
22/tcp ALLOW Anywhere
9000/tcp ALLOW Anywhere
80/tcp (v6) ALLOW Anywhere (v6)
443/tcp (v6) ALLOW Anywhere (v6)
8443/tcp (v6) ALLOW Anywhere (v6)
22/tcp (v6) ALLOW Anywhere (v6)
9000/tcp (v6) ALLOW Anywhere (v6)
9000/tcp ALLOW OUT Anywhere
9000/tcp (v6) ALLOW OUT Anywhere (v6)
I am using port 9000 for socket. But, still doesn't connect. What am I missing? I just can't figure it out and I am stuck on this for days.