laravelvpspusherlaravel-websockets

WebSocket is closed before the connection is established. Soketi app Laravel for VPS


I have a problem that lasts several days in my Laravel 10 project, I am implementing websockets using https://docs.soketi.app, on my VPS Ubunto 20.04, and in my project I have the soketi container that is running for me :

soketi:
       image: 'quay.io/soketi/soketi:latest-16-alpine'
       environment:
         SOKETI_METRICS_ENABLED: 1
       ports:
         - '6001:6001'
         - '9601:9601'
       networks:
         - network_forms
       restart: always

When accessing http://127.0.0.1:6001 and http://xx.xxx.xx.xxx:6001, both receive OK

In my .env file I have the following settings defined:

PUSHER_APP_ID=application id
PUSHER_APP_KEY=application key
PUSHER_APP_SECRET=application secret
PUSHER_HOST=localhost
PUSHER_PORT=6001
PUSHER_SCHEME=http
PUSHER_APP_CLUSTER=mt1

In the config/broadcasting.php file I have:

'pusher' => [
               'driver' => 'pusher',
               'key' => env('PUSHER_APP_KEY'),
               'secret' => env('PUSHER_APP_SECRET'),
               'app_id' => env('PUSHER_APP_ID'),
               'options' => [
                   'host' => env('PUSHER_HOST') ?: 'api-'.env('PUSHER_APP_CLUSTER', 'mt1').'.pusher.com',
                   'port' => env('PUSHER_PORT', 443),
                   'schema' => env('PUSHER_SCHEME', 'https'),
                   'encrypted' => true,
                   'useTLS' => env('PUSHER_SCHEME', 'https') === 'https',
               ],
               'customer_options' => [
                   // Guzzle client options: https://docs.guzzlephp.org/en/stable/request-options.html
               ],
           ],

To finish, I have in bootstrap.js:

import echo from 'laravel-echo';

import Pusher from 'pusher-js';
window.Pusher = Pusher;

window.Echo = new echo({
       broadcaster: 'pusher',
       key: import.meta.env.VITE_PUSHER_APP_KEY,
       cluster: import.meta.env.VITE_PUSHER_APP_CLUSTER ?? 'mt1',
       wsHost: import.meta.env.VITE_PUSHER_HOST ?? `ws-${import.meta.env.VITE_PUSHER_APP_CLUSTER}.pusher.com`,
       wsPort: import.meta.env.VITE_PUSHER_PORT ?? 80,
       wssPort: import.meta.env.VITE_PUSHER_PORT ?? 443,
       forceTLS: (import.meta.env.VITE_PUSHER_SCHEME ?? 'https') === 'https',
       encrypted: true,
       disableStats: true,
       enabledTransports: ['ws', 'wss'],
});

WebSocket connection to 'wss://localhost:6001/app/app-key?protocol=7&client=js&version=7.6.0&flash=false' failed: WebSocket is closed before the connection is established.

ProxyPass/http://localhost:6001/
    ProxyPassReverse / http://localhost:6001/

Any idea? Thanks in advance!


Solution

  • You can fix this by setting up a Nginx reverse proxy to forward requests from https://ws.your-domain.com to the local Soketi server running on your server.

    First, install the Nginx server:

    sudo apt-get install nginx
    

    Start the Nginx service and enable it to start on boot:

    sudo systemctl start nginx
    sudo systemctl enable nginx
    

    Next, configure a subdomain on your registrar pointing to your server IP address.

    And, then, secure your Nginx server by issuing a Let's Encrypt certificate.

    Finally, configure the Nginx default site configuration file to forward the requests to 127.0.0.1:6001, where Soketi is running locally.

    Open the Nginx configuration file:

    sudo nano /etc/supervisor/conf.d/soketi.conf
    

    And then, replace the existing location block with the following configuration:

    location / {
            proxy_pass             http://127.0.0.1:6001;
            proxy_read_timeout     60;
            proxy_connect_timeout  60;
            proxy_redirect         off;
    
            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;
    }
    

    With this setup, any WebSocket connection established to wss.your-domain.com will be received by the secure Nginx server and forwarded to the local Soketi server.

    Source, personal article: https://medium.com/@viniciusamparo/setting-up-a-soketi-server-and-securely-forwarding-requests-with-nginx-reverse-proxy-62aca2cfc8c1