Laravel Websocket from scratch.

In my current Laravel project I had to implement Websockets so I started to follow Laravel’s documentation, which is pretty good, but there is just so much to configure and so many packages to add that I started to look into alternatives. Basically I didn’t want to add Supervisor to the project architecture because I just want to keep third party applications to the minimum. Also I didn’t want to go with Ratchet either because its requirements.

With that said I narrowed my known solutions to basically do it all with javascript. In this post I will tell you how I setup the socket and how I configure nginx in order to handle all request through port 80.

As the project is in Laravel I use Homestead for development. All sites are served with nginx and php-fpm on port 80. In addition the project uses Redis for caching and from now on, to publish notifications to subscribed clients (it has this feature too, pretty cool right?).

But lets begin, Homestead already comes with Redis, Nginx, php-fpm and Node so I won’t cover the part of their installation. First, we define all dependencies needed by the project and then we install them:

Ssh into Homestead machine and go to vagrant shared folder, in my case is/home/vagrant/code and run:

We are one step away from our goal, now we need to tell Laravel to connect to Redis. In order to do that just edit .env and add this line (or edit if it already in there).

BROADCAST_DRIVER=redis

If your project already connects to Redis because it uses for cache or db, then this last step is optional.

You now have 2 urls available in your browser.

http://local.socket.com/

http://local.socket.com/client/info . You can replace “info” with any word here, but you’ll only see results are the ones in the form displayed at the homepage: success, info, danger and warning

When you type something in the input and choose the alert type you want to publish, that message is sent to all socket clients listening for that type of messages.

Here is the list of technologies that we used to build all this:

Laravel Homestead: it already has all applications installed but pm2.

Nginx: serves php pages and handle socket requests and responses.

Socket.io: server and client. The server is a standalone script that listens all requests coming from a given port (this actually is done by express) and when a connection is establish, it subscribes to the specified Redis channel. This channel must be the same one specified in [email protected]

Laravel Predis to handle Redis connection.

The workflow of the entire process is like this:

First, submit the information you want to broadcast, that is done by the form. Then /notify action takes all that info, process it and publish it to Redis channel. Basically, it does that with these 2 lines:

$redis = \Redis::connection();
$redis->publish('alerts', $alert);

Then Redis notifies all clients subscribed to that channel, in this case, our websocketServer script which subscribes to the channel once the connection is done (when the /client/info url is loaded).

The /client url only connects to the websocket url (http://local.socket.com/socket) all socket communication under this protocol is done on this url. Notice that /socket is the same rule we added in nginx configuration file. All request coming from /socket will be handle by the websocket Upstream.

In order to make each alert type to only “listen” for its own messages what I did was to tell which kind of messages the client has to take care about. It was pretty easy defining that variable in the route.

PM2 is only to keep websocketServer script running all the time.

There must better ways to do this I know but I haven’t research all this very deep as it is the first time I implement all this.

I hope this would be helpful for you if you need implement something similar.