Laravel Echo

broken image


We have just finished our transition from a websocket server based on laravel-echo-server to one that is fully driven by PHP: laravel-websockets. In this post, we'll highlight why and how we made that move.

Laravel Echo

Simplifying our stack #

Blade is the simple, yet powerful templating engine that is included with Laravel. Unlike some PHP templating engines, Blade does not restrict you from using plain PHP code in your templates. In fact, all Blade templates are compiled into plain PHP code and cached until they are modified, meaning Blade adds essentially zero overhead to your. Above, we are using Laravel Echo to listen for the UpdateCreated event on the updates channel. Every time a new update is added, the event above will be triggered and the callback inside the listen method will be invoked.

As we're built on Laravel, we already run a fair bit of nodejs during our build phase. Our frontend JavaScript & CSS already get compiled via webpack. So in a way, our stack already includes node to make this all happen.

Part of our smooth user experience (if we say so ourselves ;-)) comes from the use of websockets, that allows us to give instant feedback to our users in their dashboard & our homepage. To make that work, we've always used laravel-echo-server, a node implementation of a websocket server.

To make that websocket server work, you can use 2 methods: use a Redis queue or publish messages directly through HTTP. We used a Redis queue, which means the following events took place for us:

  1. Laravel publishes a message to a Redis channel
  2. The echo-server listens to new events being stored there
  3. The echo-server relays those to its subscribers/clients

This has worked very well for us, without any issues.

But we found ourselves in the unique spot to test an even simpler approach: run a websocket server fully in PHP without the need for node.

Moving to PHP #

Our initial reaction was 'but surely PHP can't handle the load a Node process could, right?'.

Well, to get started we benchmarked the laravel-websockets package using Artillery. What we found was that the websocket implementation in PHP could handle our load with great ease and keep under 50MB memory consumption.

Performance, during our testing, appeared on-par with the node implementation.

Since we weren't losing anything, we dediced to remove our node dependency for our production machines and run the entire websocket stack in PHP.

Adding TLS and supervisor #

Our setup is already using Nginx as a TLS proxy as well as Supervisor to keep all our workers running, so we already had the building blocks in place to add some configuration for our new websocket server.

We configured both Nginx and Supervisor to handle the TLS part and the job-running pretty quickly.

Transitioning from laravel-echo-server to laravel-websockets #

Code-wise, the change was a piece of cake. Unless we're forgetting something, it consisted of:

  • Remove all references to /js/socket.io.js in our frontend (we'll no longer be needing socket.io for our websockets)
  • Install laravel-websockets and follow its install instructions
  • Change our frontend-code from using socket.io to pusher

Laravel Echo Tutorial

  • Change our broadcast driver from Redis to using Pusher in .env

That was enough for us to move to laravel-websockets.

Laravel Echo Server

What did we gain? #

One of its biggest gains is in our development process: we now just need to run php artisan websocket:serve to get a local websocket server going and not have to deal with the (rather confusing) configuration of laravel-echo-server.

Laravel Echo Html

Additionally, we simplified our server setup and now fully rely on PHP without Node for running websockets. Managing less software is always a win, especially from a security angle (keeping track of the node ecosystem and the dependencies of the echo-server).

Laravel Echo Not Receiving Events

For us, it was a no-brainer to make the switch.





broken image