0

VPS GoDaddy, AlmaLinux. I'm writing a messenger and used the following technology stack: Laravel Reverb, Redis. I installed Reverb like this:

php artisan install:broadcasting

I couldn't configure the Nginx proxy (it seems that this is prohibited on this hosting), so I used Pre VirtualHost Include from Apache:

# Load required proxy modules
LoadModule proxy_module modules/mod_proxy.so
LoadModule proxy_http_module modules/mod_proxy_http.so
LoadModule proxy_wstunnel_module modules/mod_proxy_wstunnel.so

# Global proxy settings
ProxyPreserveHost On
ProxyRequests Off

# Laravel Reverb configuration for <host>
<VirtualHost *:80>
    ServerName <host>
    ServerAlias www.<host>
    DocumentRoot /home/<project>/public_html/public
    
    # WebSocket connections on /app
    RewriteEngine On
    RewriteCond %{HTTP:Upgrade} =websocket [NC]
    RewriteRule ^/app/(.*)$ ws://127.0.0.1:3000/app/$1 [P,L]
    
    # API requests on /apps
    RewriteCond %{HTTP:Upgrade} =websocket [NC]
    RewriteRule ^/apps/(.*)$ ws://127.0.0.1:3000/apps/$1 [P,L]
    
    # HTTP proxy for /app (WebSocket endpoint)
    ProxyPass /app/ http://127.0.0.1:3000/app/
    ProxyPassReverse /app/ http://127.0.0.1:3000/app/
    
    # HTTP proxy for /apps (API endpoint)
    ProxyPass /apps/ http://127.0.0.1:3000/apps/
    ProxyPassReverse /apps/ http://127.0.0.1:3000/apps/
    
    # Proxy headers (Apache equivalent for Nginx headers)
    ProxyPreserveHost On
    ProxyPass / http://127.0.0.1:3000/ connectiontimeout=5 retry=300
    ProxyPassReverse / http://127.0.0.1:3000/
    
    ErrorLog /usr/local/apache/domlogs/<host>_error.log
    CustomLog /usr/local/apache/domlogs/<host>_access.log combined
</VirtualHost>

<VirtualHost *:443>
    ServerName <host>
    ServerAlias www.<host>
    DocumentRoot /home/<project>/public_html/public
    
    # WebSocket connections on /app (HTTPS)
    RewriteEngine On
    RewriteCond %{HTTP:Upgrade} =websocket [NC]
    RewriteRule ^/app/(.*)$ ws://127.0.0.1:3000/app/$1 [P,L]
    
    # API requests on /apps (HTTPS)
    RewriteCond %{HTTP:Upgrade} =websocket [NC]
    RewriteRule ^/apps/(.*)$ ws://127.0.0.1:3000/apps/$1 [P,L]
    
    # HTTP proxy for /app
    ProxyPass /app/ http://127.0.0.1:3000/app/
    ProxyPassReverse /app/ http://127.0.0.1:3000/app/
    
    # HTTP proxy for /apps
    ProxyPass /apps/ http://127.0.0.1:3000/apps/
    ProxyPassReverse /apps/ http://127.0.0.1:3000/apps/
    
    # Headers for WebSocket over SSL
    <Location "/app/">
        ProxyPass http://127.0.0.1:3000/app/
        ProxyPassReverse http://127.0.0.1:3000/app/
        ProxyPreserveHost On
        
        # Apache equivalent of Nginx headers
        Header always set "Upgrade" "%{HTTP:Upgrade}i"
        Header always set "Connection" "%{HTTP:Connection}i"
        SetEnvIf X-Forwarded-Proto https HTTPS=on
    </Location>
    
    <Location "/apps/">
        ProxyPass http://127.0.0.1:3000/apps/
        ProxyPassReverse http://127.0.0.1:3000/apps/
        ProxyPreserveHost On
    </Location>
    
    ErrorLog /usr/local/apache/domlogs/<host>_ssl_error.log
    CustomLog /usr/local/apache/domlogs/<host>_ssl_access.log combined
</VirtualHost>

.env variables:

# --- Reverb (Broadcast Driver) ---
BROADCAST_DRIVER=reverb
REVERB_SERVER_HOST=127.0.0.1
REVERB_SERVER_PORT=3000
REVERB_APP_ID=<id>
REVERB_APP_KEY=<key>
REVERB_APP_SECRET=<secret>
REVERB_HOST="<host>"
REVERB_PORT=443
REVERB_SCHEME=https
REVERB_CLUSTER=mt1

VITE_REVERB_APP_KEY=${REVERB_APP_KEY}
VITE_REVERB_HOST=${REVERB_HOST}
VITE_REVERB_PORT=443
VITE_REVERB_SCHEME=https
VITE_REVERB_CLUSTER="${REVERB_CLUSTER}"

QUEUE_CONNECTION=redis
#Other redis settings

config/broadcasting.php:

return [
    /*
    |--------------------------------------------------------------------------
    | Default Broadcaster
    |--------------------------------------------------------------------------
    |
    | This option controls the default broadcaster that will be used by the
    | framework when an event needs to be broadcast. You may set this to
    | any of the connections defined in the "connections" array below.
    |
    */

    'default' => env('BROADCAST_DRIVER', 'reverb'),

    /*
    |--------------------------------------------------------------------------
    | Broadcast Connections
    |--------------------------------------------------------------------------
    |
    | Here you may define all of the broadcast connections that will be used
    | to broadcast events to other systems or over websockets. Samples of
    | each available type of connection are provided inside this array.
    |
    */

    'connections' => [
        'reverb' => [
            'driver' => 'pusher',
            'key' => env('REVERB_APP_KEY'),
            'secret' => env('REVERB_APP_SECRET'),
            'app_id' => env('REVERB_APP_ID'),
            'options' => [
                'host' => env('REVERB_HOST', '127.0.0.1'),
                'port' => env('REVERB_PORT', 8080),
                'scheme' => env('REVERB_SCHEME', 'http'),
                'cluster' => env('REVERB_CLUSTER', 'mt1'),
                'useTLS' => env('REVERB_SCHEME', 'http') === 'https',
            ],
        ],

        'redis' => [
            'driver' => 'redis',
            'connection' => 'default',
        ],

        'pusher' => [
            'driver' => 'pusher',
            'key' => env('PUSHER_APP_KEY'),
            'secret' => env('PUSHER_APP_SECRET'),
            'app_id' => env('PUSHER_APP_ID'),
            'options' => [
                'cluster' => env('PUSHER_APP_CLUSTER'),
                'useTLS' => true,
            ],
        ],

        'ably' => [
            'driver' => 'ably',
            'key' => env('ABLY_KEY'),
        ],

        'log' => [
            'driver' => 'log',
        ],

        'null' => [
            'driver' => 'null',
        ],
    ],
];

config/reverb.php:

return [

    /*
    |--------------------------------------------------------------------------
    | Default Reverb Server
    |--------------------------------------------------------------------------
    |
    | This option controls the default server used by Reverb to handle
    | incoming messages as well as broadcasting message to all your
    | connected clients. At this time only "reverb" is supported.
    |
    */

    'default' => env('REVERB_SERVER', 'reverb'),

    /*
    |--------------------------------------------------------------------------
    | Reverb Servers
    |--------------------------------------------------------------------------
    |
    | Here you may define details for each of the supported Reverb servers.
    | Each server has its own configuration options that are defined in
    | the array below. You should ensure all the options are present.
    |
    */

    'servers' => [

        'reverb' => [
            'host' => env('REVERB_SERVER_HOST', '0.0.0.0'),
            'port' => env('REVERB_SERVER_PORT', 8080),
            'path' => env('REVERB_SERVER_PATH', ''),
            'hostname' => env('REVERB_HOST'),
            'options' => [
                'tls' => [],
            ],
            'max_request_size' => env('REVERB_MAX_REQUEST_SIZE', 10_000),
            'scaling' => [
                'enabled' => env('REVERB_SCALING_ENABLED', false),
                'channel' => env('REVERB_SCALING_CHANNEL', 'reverb'),
                'server' => [
                    'url' => env('REDIS_URL'),
                    'host' => env('REDIS_HOST', '127.0.0.1'),
                    'port' => env('REDIS_PORT', '6379'),
                    'username' => env('REDIS_USERNAME'),
                    'password' => env('REDIS_PASSWORD'),
                    'database' => env('REDIS_DB', '0'),
                    'timeout' => env('REDIS_TIMEOUT', 60),
                ],
            ],
            'pulse_ingest_interval' => env('REVERB_PULSE_INGEST_INTERVAL', 15),
            'telescope_ingest_interval' => env('REVERB_TELESCOPE_INGEST_INTERVAL', 15),
        ],

    ],

    /*
    |--------------------------------------------------------------------------
    | Reverb Applications
    |--------------------------------------------------------------------------
    |
    | Here you may define how Reverb applications are managed. If you choose
    | to use the "config" provider, you may define an array of apps which
    | your server will support, including their connection credentials.
    |
    */

    'apps' => [

        'provider' => 'config',

        'apps' => [
            [
                'key' => env('REVERB_APP_KEY'),
                'secret' => env('REVERB_APP_SECRET'),
                'app_id' => env('REVERB_APP_ID'),
                'options' => [
                    'host' => env('REVERB_HOST'),
                    'port' => env('REVERB_PORT', 443),
                    'scheme' => env('REVERB_SCHEME', 'https'),
                    'useTLS' => env('REVERB_SCHEME', 'https') === 'https',
                ],
                'allowed_origins' => ['*'],
                'ping_interval' => env('REVERB_APP_PING_INTERVAL', 60),
                'activity_timeout' => env('REVERB_APP_ACTIVITY_TIMEOUT', 30),
                'max_message_size' => env('REVERB_APP_MAX_MESSAGE_SIZE', 10_000),
            ],
        ],

    ],

];

resources/js/echo.js:

import Echo from 'laravel-echo';
import Pusher from 'pusher-js';

window.Pusher = Pusher;

const echoConfig = {
    broadcaster: 'pusher',
    key: import.meta.env.VITE_REVERB_APP_KEY,
    wsHost: import.meta.env.VITE_REVERB_HOST || window.location.hostname,
    wsPort: import.meta.env.VITE_REVERB_PORT || window.location.port,
    forceTLS: (import.meta.env.VITE_REVERB_SCHEME || window.location.protocol) === 'https:',
    enabledTransports: ['ws', 'wss'],
    cluster: import.meta.env.VITE_REVERB_CLUSTER || 'mt1',
    authEndpoint: '/broadcasting/auth',
    auth: {
        headers: {
            'X-CSRF-TOKEN': document.querySelector('meta[name="csrf-token"]')?.content,
        },
    },
};

if (!echoConfig.key) {
    console.error('REVERB_APP_KEY is not defined');
} else {
    window.Echo = new Echo(echoConfig);
}

Starting reverb server (due to weird settings of the hosting):

/opt/cpanel/ea-php83/root/usr/bin/php artisan reverb:start --host=127.0.0.1 --port=3000 --debug -vvv

And in this debug output I'm getting an error:

[ERROR] Laravel\Reverb\Protocols\Pusher\Http\Controllers\PusherController::__invoke(): Argument #2 ($connection) must  
         be of type Laravel\Reverb\Servers\Reverb\Connection, Laravel\Reverb\Servers\Reverb\Http\Connection given,      
         called in /home/<project>/public_html/vendor/laravel/reverb/src/Servers/Reverb/Http/Router.php on line 74

Updating packages does not help. Package "laravel/reverb": "^1.5". Please explain to me how to solve this issue, cause my connections failed:

echo-B7dTUkUW.js:8 WebSocket connection to 'wss://<host>/app/<key>?protocol=7&client=js&version=8.4.0&flash=false' failed

0

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.