Migrating from beyondcode/laravel-websockets to Laravel Reverb

Live communication with Laravel and Echo is such a great thing! I am currently using beyondcodes laravel-websockets package, but as this is not longer maintained, I have to switch to Laravel Reverb. I have currently a Laravel 10 application (which is permanently upgraded starting from 5.6). Now I want to upgrade to Laravel 11 since a year 😉 so I have to replace laravel-websockets with Laravel Reverb. Let’s go! (**)

This is how I did it, maybe it helps someone:

Current configuration is a default installation of laravel-websockets, with default configuration, the socket server is listening on port 6001. For getting websockets up and running behind an nginx reverse proxy and on a local dev machine, i have the following configuration (yes, hard coded) in my app.js.

const { default: Echo } = require('laravel-echo');

window.echo = window.Echo = new Echo({
    broadcaster: 'pusher',
    key: 'wsSOLApp',
    cluster: 'mt1',
    encrypted: true,
    wsHost: window.location.hostname,
    wssHost: window.location.hostname,
    wsPort: 6001,
    wssPort: 443,
    forceTLS: window.location.hostname == 'localhost' ? false : true,
    disableStats: true,
    enabledTransports: ['ws', 'wss'],
});

First, I remove the laravel-websocket package

composer remove beyondcode/laravel-websockets

Then I install Laravel Reverb (since I am on Laravel 10 I can’t use php artisan install:broadcasting): first I require the package from composer, secondly I install reverb in the application via artisan:

composer require laravel/reverb
php artisan reverb:install

The last command creates a config/reverb.php file.

NOTE: I am installing Reverb after this documentation on another production server, which is configured slightly different (eg. no octane (yet), no proxy). Additions here unter „NOTES“: reverb requires in composer.json the pusher/pusher-php-server to be ^7.2 first, then require laravel/reverb.

Then I changed the Echo config object in my app.js to wsPort:8080, I added all the REVERB_xxx keys in my .env, and I changed the REVERB_APP_KEY to wsSOLApp in my .env. This looks like so:

REVERB_APP_ID=aaaaaaaaaaaaaaaaaaaa
REVERB_APP_KEY=wsSOLApp
REVERB_APP_SECRET=bbbbbbbbbbbbbbbbbbb
REVERB_HOST="localhost"
REVERB_PORT=8080
REVERB_SCHEME=http

In config/broadcasting.php I duplicated the „pusher“ array key and renamed it to „reverb“. I updated the REVERB_APP_ID and the REVERB_APP_SECRET according to the existing values from config/broadcasting.php. And I changed the port in config/broadcasting.php to 8080.

This is the whole definition in config/broadcasting.php under the connections key:

        'reverb' => [
            'driver' => 'reverb',
            'key' => 'wsSOLApp',
            'secret' => 'bbbbbbbbbbbbbbbbbbb',
            'app_id' => 'aaaaaaaaaaaaaaaaaaaa',
            'options' => [
                'cluster' => 'mt1',
                'useTLS' => false,
                'host' => '127.0.0.1',
                'port' => 8080,
                'scheme' => 'http',
                'encrypted' => true,
                'curl_options' => [
                    CURLOPT_SSL_VERIFYHOST => 0,
                    CURLOPT_SSL_VERIFYPEER => 0,
                ],
            ],
        ],

Now the local php artisan serve started correctly. Before duplicating and renaming the array key from pusher to reverb, it was telling me „Broadcast connection [reverb] is not defined“ and aborted.

Also php artisan reverb:start seems to start perfectly fine on 0.0.0.0:8080.

I started it with the –debug flag.

But what should I say? After logging in to my application on my dev machine, the reverb server already seems to be working fine!

{"event":"pusher:connection_established","data":"{\"socket_id\":\"991187678.701316654\",\"activity_timeout\":30}"}
{"event":"pusher:subscribe","data":{"auth":"","channel":"new-appointment"}}
{"event":"pusher_internal:subscription_succeeded","data":"{}","channel":"new-appointment"}
{"event":"pusher:ping","data":{}}
{"event":"pusher:pong"}

In my application, I have one component which uses the websockts connection heavily, after extensive testing it seems to work perfectly fine!

One thing is irritating me… the driver in config/broadcasting.php seems to be still „pusher“. I don’t find anything in the docs, so what? With the value „pusher“, it works… Mhmm? Okay, I install a new test application with Laravel 11, install broadcasting with Reverb and look at the config/broadcasting.php: It says: driver => ‚reverb‘. Okay, now that’s strange.

So: check!

Now let’s move on to the production server. First I deployed this changes to production and now let’s see, what’s missing:

Okay, installation was successfull, now I do the following steps:

In supervisor I renamed the laravel-websockets.conf to laravel-reverb.conf and replaced the command to php artisan reverb:start.

Then I reloaded supervisor.

After that I removed the 6001/tcp from ufw with

sudo ufw status numbered

Status: active

     To                         Action      From
     --                         ------      ----
[ 1] Nginx Full                 ALLOW IN    Anywhere                  
[ 2] OpenSSH                    ALLOW IN    Anywhere                  
[ 3] 6001/tcp                   ALLOW IN    Anywhere                  
[ 4] Nginx Full (v6)            ALLOW IN    Anywhere (v6)             
[ 5] OpenSSH (v6)               ALLOW IN    Anywhere (v6)             
[ 6] 6001/tcp (v6)              ALLOW IN    Anywhere (v6) 

sudo ufw delete 3

Deleting:
 allow 6001/tcp
Proceed with operation (y|n)? y  

Then repeat this commands, the 6001/tcp (v6) should now be rule #5.

Now I add 8080/tcp to the ufw again:

sudo ufw add 8080/tcp

Then I ssh-ed into my proxy server and replaced the port forwarding from 6001 to 8080 in the nginx config file:

Ahhh yes, last but not least I set the .env variables of REVERB at the production server.

Now let’s test again:

No, websocket „Application does not exist“.

Mhmm?

Oooops, it took me 10 minutes to find out, but thankfully very easy: clear the config cache. Then once again restart octane via supervisor, and check!

Wow, that actually only took a quarter of a day! Thanks to the beyondcode-team for the work on laravel-websockets until now, and thanks to the laravel team for working on reverb from now 😉

One addition: Change the BROADCAST_DRIVER in your .env to reverb ;-). And note, in Laravel 11 this is called BROADCAST_CONNECTION…

NOTE: The above note was the only one 😉

(**) Perhaps you can read between the lines: I started this article almost a year ago, then I had so many other things to do first…