Real time with Reverb
Switch on the optional WebSocket server so add-on payments and the notification bell update on their own, locally and on a Ploi server.
The kit ships with real time switched off. With it off, everything works as it always has: the add-on screens ask the server every few seconds while a payment is waiting, and the notification bell shows what there was when the page loaded. Switch it on and two things react within a second, with no polling:
| Screen | With real time off | With real time on |
|---|---|---|
| Add-on catalogue and add-on detail, after paying | Polls every 3 seconds (catalogue) or 5 seconds (detail) until Stripe confirms the payment | No polling. Every Stripe webhook about the account tells its open billing screens to check, and the confirmation shows as soon as the webhook lands |
| Notification bell in the top bar | Counter and list are loaded with the page | A new notification updates the counter and the list in every open tab of the person it was sent to, and only of that person |
The decision is the application's, not each screen's: real time is on when BROADCAST_CONNECTION is reverb, and off with any other value. There is no fallback: if Reverb is on and its server is down, nothing breaks, the screens simply stop updating on their own until it is back (a payment is still confirmed; the person sees it on reload).
Reverb is a process of its own that runs on the same server as the application, so it shares that server's memory and processor. It is light, but it is one more thing to keep alive, which is why the kit leaves the choice to each product.
What is involved
- Server side.
laravel/reverbis the WebSocket server. Broadcasting is immediate (ShouldBroadcastNow), so it does not need the queue worker. - Browser side.
laravel-echoandpusher-jsare bundled inresources/js/bootstrap.js. The layout only hands the browser the connection settings when the person is signed in and real time is on, so a visitor without a session, or any page with real time off, never opens a connection. - Channels. Two private channels, both authorised at
POST /broadcasting/auth:App.Models.User.{id}(only that user, declared inroutes/channels.php) carriesnotification.received;billing-account.{id}(only someone who can manage that billing account, declared by Billing Core) carriesbilling-account.updated.
Try it locally
-
Make sure the dependencies are installed:
composer installandnpm install(laravel/reverb,laravel-echoandpusher-jscome with the kit). -
Add to your local
.env. The three app values are any random strings you choose;php -r "echo bin2hex(random_bytes(16));"makes one.BROADCAST_CONNECTION=reverb REVERB_APP_ID=local REVERB_APP_KEY=a-random-string REVERB_APP_SECRET=another-random-string REVERB_HOST=weblabor-base.test REVERB_PORT=8080 REVERB_SCHEME=httpsUse your own site name in
REVERB_HOST. Do not runphp artisan reverb:installorphp artisan install:broadcasting: the kit is already wired, and both commands rewrite files it owns. -
Start the server, naming the secured Herd or Valet site so Reverb serves TLS with its certificate (an
httpspage cannot open a plainws://connection):php artisan reverb:start --hostname=weblabor-base.test --debug -
php artisan config:clear, thennpm run dev(ornpm run build) and reload the page. With--debugthe terminal prints each connection and each message. -
Check both cases. Buy an add-on with a Stripe test card and the confirmation appears as soon as the webhook arrives (forward webhooks with
stripe listenlocally), with nocheckSubscriptionStatusorcheckPendingrequests repeating in the network tab. Then make a notification reach someone, for example answer their ticket from another account, and their bell changes without a reload while another signed-in person's does not.
Switch it on or off
On: set BROADCAST_CONNECTION=reverb with the REVERB_* values, start the Reverb process, and run php artisan config:clear (or php artisan optimize if you cache the configuration). Off: set BROADCAST_CONNECTION=null (or remove it, null is the default), run the same command, and stop the process. Nothing needs rebuilding: the browser reads the settings from the page, not from the bundle.
Deploy it on Ploi
Ploi keeps processes alive with Supervisor and serves the site with Nginx. It can run Reverb for you, but it does not write the Nginx block that forwards the WebSocket traffic: that part is yours.
-
Supervisor. Reverb runs as a Ploi daemon, and daemons run under Supervisor, so Supervisor has to be installed and running on the server. A server that already runs the queue worker as a Ploi daemon has it; on a new one, check it among the server's services before adding the daemon.
-
The Reverb process. In the server's Daemons, add one:
Field Value Command php /home/ploi/your-domain.com/artisan reverb:start --host=127.0.0.1 --port=8080User ploiProcesses 1It listens only on the server itself, port 8080; Nginx is the only thing that reaches it.
-
Nginx. In the site's Manage, open the Nginx configuration and add, inside the
serverblock that listens on 443, the two routes Reverb uses:/appfor the browsers' WebSocket connections and/appsfor the application publishing events.location /app { proxy_http_version 1.1; proxy_set_header Host $http_host; proxy_set_header Scheme $scheme; proxy_set_header SERVER_PORT $server_port; proxy_set_header REMOTE_ADDR $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "Upgrade"; proxy_pass http://127.0.0.1:8080; } location /apps { proxy_http_version 1.1; proxy_set_header Host $http_host; proxy_set_header Scheme $scheme; proxy_set_header SERVER_PORT $server_port; proxy_set_header REMOTE_ADDR $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "Upgrade"; proxy_pass http://127.0.0.1:8080; }Save it; Ploi tests and reloads Nginx.
-
Environment. In the site's environment, with your own random values:
BROADCAST_CONNECTION=reverb REVERB_APP_ID=your-app-id REVERB_APP_KEY=your-app-key REVERB_APP_SECRET=your-app-secret REVERB_HOST=your-domain.com REVERB_PORT=443 REVERB_SCHEME=httpsREVERB_HOST,REVERB_PORTandREVERB_SCHEMEare the public address, the one Nginx answers on, used both by the browsers and by the application to publish. The process itself keeps listening on 127.0.0.1:8080. -
Deploy script. The usual commands already rebuild the application's assets (
npm ciandnpm run build), which is what bundles Echo; keep them. Add, afterphp artisan queue:restart:php artisan reverb:restartLike the queue worker, Reverb keeps the code it started with in memory, and this is what makes Supervisor start it again with the new release.
The Ploi steps are documented here but not tested by the kit. After the first deploy, open a page signed in and check in the browser's network tab that the connection to wss://your-domain.com/app/... opens with status 101.