Creating a Real Time Web App with Pusher

A few years ago I went through a phase of being "into" real-time web applications. I did a couple of experiments with Websockets (in particular SocketIO) and got some interesting results. I even included an aspect of this in my university dissertation.

I thought I would revisit this to remind myself of how it works and see what new things have happened.

It seems that it is even easier now than ever before to get started with real-time web applications. Where as before I built a websocket server that had to be on and handle the messages, there are now services that do all of this for you.

An example of this is Pusher. They provide the service for building real time web applications along with tools to monitor usage and a really simple API that does most of the work for you.

There is a free tier that is especially good if you just want to have a play. I won't go into details here how to sign up or a guide to their interface because they do a pretty good job of all that and it is pretty straight forward.

In fact, they even provide a very easy to follow basic code in whatever language you are using, to get you started (some of which this demo is based off).

The demo will build a very basic chat room with no rules or security at all. You just go on and send messages and they appear for everyone that is viewing the page.

HTML

I have put together a very basic HTML page with some help from Bootstrap as well as some inline styles.

The bulk of it looks like this:

<div class="container">
    <h1 class="text-center">My Chat Room</h1>
    <div class="row">
        <p class="col-xs-12">Messages:</p>
        <div id="messages" class="col-xs-12" style="height:400px; overflow-y: scroll; border: 5px solid #000;"></div>
        <div class="col-xs-12" style="margin-top: 20px;">
            <input type="text" id="my_message" class="col-xs-8" />
            <button id="send_message" class="col-xs-4">Send</button>
        </div>
    </div>
</div>

Which gives an output that looks like this:

The idea is that when I type something into the text box and click Send, it will update the messages box. This would happen on all who are logged onto the page.

First, let's handle receiving messages from Pusher.

Receiving Messages from Pusher

First I create a new app. It rather helpfully provides a clear example of how to use their library based on what technologies you use. So it is useful to select this albeit optional:

Now back to our code.

First, I need to load the Pusher library into the web page:

<script src="https://js.pusher.com/4.1/pusher.min.js"></script>

Next, I need to connect to the API, using my key. The demo code they provide has this boiler plate:

var pusher = new Pusher('api-key-goes-here', {
    cluster: 'eu',
    encrypted: true
 });

Finally, I open up a connection and start listening to a particular channel:

var channel = pusher.subscribe('messages');

I could have called this channel anything I wanted, but I named it "messages" in this case.

It should be obvious at this stage that I could have multiple different channels, listening to different things.

Now, I can tell it what to do when it receives data from the channel:

channel.bind('message-received', function(data) {
     alert(data.message);
});

Again, I could have different names for the events being sent, but I call it "message-recieved". You can see that I specify a function that gets the data as an argument. This data is in the form of JSON so can be accessed as such.

In this case, I am simply opening an alert showing what is in the message key.

I can test this using the Pusher debug console where I created the app.

It allows me to send a message on a channel and with a label that I specify with any data that I like to this particular app:

You can see my data is in the form of JSON and I have a key called "message" with the text, "Hello". You can also see underneath all that, that is has acknowledged the fact that there is one client online and listening to this app.

Sending the message causes the pop-up to show with my message there:

Thus proving that my front end is successfully connected.

Now we just have to make it do something a little more useful, that is, put the message inside the box. This can be done with a single line replacing the alert:

$('#messages').append('<p>'+ data.message +'</p>');
Server Side

So now we are successfully receiving messages and updating our screen accordingly. Now we want to be able to actually send messages from our browser.

To do this, we need some code on the server side to receive a message from the browser then send it on to Pusher. I have created a file called "message_processor.php".

First we need to install the Push SDK again. We can use composer for this which is great. So in my composer JSON file, I have the line:

"pusher/pusher-php-server": "v3.0.*"

Then I can just include it into my server file by requiring the vendor autoload file:

require __DIR__ . '/vendor/autoload.php';

Now I want to check if I have received a post request with the message and if I have run some code:

if ($_POST['message'] && !empty($_POST['message'])) {
    $message = $_POST['message'];
}

Next, within the if-statement, I wan to connect to the app again. As you can see, I pass the app id and the API key and secret key. These can be found under App Keys tab on the pusher website.

$options = [
    'cluster' => 'eu',
    'encrypted' => true
];
$pusher = new Pusher\Pusher(
    'KEY',
    'SECRET',
    'APPID',
    $options
);

Finally, I can now simply use my pusher object to broadcast the message to the app:

$data = [
    'message' => $message
];
$pusher->trigger('messages', 'message-received', $data);

As you can see, I am forming an array to send. I then call the trigger function with channel that I am sending it to and the label for that message. It seems silly sending back the message that I just sent, but remember, everyone who is currently on that page will see it appear like magic on their screen.

Connecting it all up with AJAX

Now that I have done the backend code, I want to send a message to it when I press the button. To do this, I make a simple click event function and within this function, I call some AJAX (I covered AJAX in last week's post!):

$('#send_message').click(function(e){
    e.preventDefault();
    $.ajax({
        url: "/pusherdemo/message_processor.php",
        data: {
            message: $('#my_message').val(),
        },
        type: "POST",
        dataType: "json",
        beforeSend: function() {
            $('#send_message').attr('disabled', 'disabled');
        },
        success: function(json) {},
        complete: function(json) {         
            $('#send_message').removeAttr('disabled');
            $('#my_message').val('');
        }
     });
    return false;
});

As you can see, it sends the contents of the input to the message processor and then clears it. It doesn't do anything in success because it doesn't need to.

Again, it seems a bit weird not using the success function to update the messages, but remember, only YOU would see that. This way, everyone on this chat room will see the message that you just sent.

Now I can't really demonstrate it in the blog post, but all of the above code does work. Here is a screenshot of 2 different browsers both connected to the same page. You can see the messages that I already sent have appeared on both even though I only sent from one:

Summary

Once again, I have only scratched the surface with what is possible with WebSockets and Pusher with an incredibly simplified demo.

But I hope it shows just how quick it is to get started!


© 2012-2018