Broadcasting events with Pusher.com & Socket.io in Laravel 5.1

Posted on April 28, 2015 | By Matt Stauffer


Warning: This post is over a year old. I don't always update old posts with new information, so some of this information may be out of date.

Taylor's put up a new Laracast video about using the new Broadcasting tool in Laravel 5.1, which is a simple contract that allows you to "broadcast" any Event out to Pusher.com or a Redis-backed Socket.io instance.

What are Pusher.com and Socket.io?

These are tools that use websockets to open a direct connection to your user's web browser so that you can push events directly to the user without reloading their page view.

If you've ever been on a web page and gotten "push" notifications of events (for example, when Laravel Forge updates the status of your server without you reloading the page), it's likely it was using websockets to open the connection between your browser and a server somewhere. Pusher.com is a hosted SaaS that makes it super easy to set it up, but you can also set up your own server using Socket.io.

How do websockets work?

I'll save you from most of the technical details, but just know: There's a direct connection being opened between a web browser and a backend server. The server can push "events" (which each have a name and optionally a payload of data) along "channels". So, for example, Forge might have a "server-status" channel which can push out an event every time a server's status changes.

So if you set up Pusher.com to handle your websockets, you'll install a Javascript-based client on the frontend, and then use the Pusher PHP SDK to "push" events from your server to Pusher.com, which will then push them to the client.

So, what are Laravel broadcast events?

If you're not familiar, check out how Laravel 5 events work. So, we now know that we can fire events--in the Forge event, maybe it would be a ServerUpdated event.

// ServerControllerOrSomething.php
    public function update()
    {
        // Do updating stuff...

        // Now send event
        event(new ServerUpdated($server));
    }

In the past, if you wanted to push a websocket notification to your users here, you would pull in the Pusher SDK, and manually send a notification over to Pusher.com in the event handler.

Now, you just add two things to your event: a ShouldBroadcast interface and a broadcastOn method.

Updating your Event to be broadcast-friendly

Check it out:

<?php

use Illuminate\Contracts\Broadcasting\ShouldBroadcast;

class ServerUpdated implements ShouldBroadcast
{
    public $server;

    public function __construct($server)
    {
        $this->server = $server;
    }

    public function broadcastOn()
    {
        return ['server-updates'];
    }
}

As you can see, the broadcastOn method just sends back an array, and as you can guess from what we talked about earlier, this array is a list of all of the Pusher channels we want to broadcast this event on.

Payload

Every public property on your event will be sent along as a part of the Pusher payload. Protected or private properties won't be sent along.

Note that we passed in an Eloquent object $server on ours; since Eloquent objects are JSONable, the $server object will be converted to JSON and delivered with the payload.

Using these events in our client-side code

You'll want to follow the Pusher directions to get your client code up and running, but you'll end up with something like this:

var serverChannel = pusher.subscribe('server-status');
serverChannel.bind('ServerUpdated', function(message) {
    console.log(message); // Full payload
});

Config

There's a new config/broadcasting.php configuration file that allows you to set up your connections and pass in which each instance should be using.

The three possible drivers right now are Pusher.com, Socket.io, and log, which just writes it out to a local log file for testing:

[2015-04-28 20:00:00] local.INFO: Broadcasting [ServerUpdated] on channels [server-status] with payload:
{
    "server": {
        "id": 1
    }
}

Conclusion

Now there are even less barriers getting in the way of you adding websockets to your app. Set your Event to broadcast, plug it into a Pusher.com account, and then pull in the Pusher client on your frontend and you're up and running!


Comments? I'm @stauffermatt on Twitter


Tags: laravel  •  laravel 5.1