The tutorial for PHP WebSockets that I wish had existed...

by Samuel Attard

About a year ago now I decided I wanted to move away from AJAX serving updates to dynamic content and into the future that is WebSockets. If you don't know what WebSockets are you should probably stop reading this and go find out all about them.

So here I am thinking "Yes, let's go use websockets" and then hitting a brick wall. All the nice solutions it seemed were written for node (WebSockets were designed for JS after all). After a bit of Googling I found what appeared to be the solution for me. Enter Ratchet

Here is where the going got tricky, so here is where the tutorial begins. Once you are through with these steps you should having working a working PHP WebSocket server persisting on your server.

First off, the Dependencies

Ratchet uses composer to manage its dependencies, if you don't know how to install composer just check out the Composer Website. To include ratchet just add the following to the requires sections of your composer.json file.

"require": {
    "cboden/ratchet": "0.3.*"

Next up, the server script

Now we have ratchet available to use we can start a basic WebSocket server with the following two files.
First we have socket.php

require 'vendor/autoload.php';  
use Ratchet\MessageComponentInterface;  
use Ratchet\ConnectionInterface;

require 'chat.php';

// Run the server application through the WebSocket protocol on port 8080
$app = new Ratchet\App("localhost", 8080, '', $loop);
$app->route('/chat', new Chat, array('*'));


Then we have chat.php

use Ratchet\MessageComponentInterface;  
use Ratchet\ConnectionInterface;

class Chat implements MessageComponentInterface {  
    public $clients;
    private $logs;
    private $connectedUsers;
    private $connectedUsersNames;

    public function __construct() {
        $this->clients = new \SplObjectStorage;
        $this->logs = [];
        $this->connectedUsers = [];
        $this->connectedUsersNames = [];

    public function onOpen(ConnectionInterface $conn) {
        echo "New connection! ({$conn->resourceId})\n";
        $this->connectedUsers [$conn->resourceId] = $conn;

    public function onMessage(ConnectionInterface $from, $msg) {
        // Do we have a username for this user yet?
        if (isset($this->connectedUsersNames[$from->resourceId])) {
            // If we do, append to the chat logs their message
            $this->logs[] = array(
                "user" => $this->connectedUsersNames[$from->resourceId],
                "msg" => $msg,
                "timestamp" => time()
        } else {
            // If we don't this message will be their username
            $this->connectedUsersNames[$from->resourceId] = $msg;

    public function onClose(ConnectionInterface $conn) {
        // Detatch everything from everywhere

    public function onError(ConnectionInterface $conn, \Exception $e) {

    private function sendMessage($message) {
        foreach ($this->connectedUsers as $user) {

Testing these scripts quickly

To quickly see if these are working, navigate to the folder that contains socket.php and open a command window. Run the command php socket.php, your websocket should now be running.

To see it in operation a great tool to use is this chrome extension Simple Websocket Client. If you try to connect to ws://localhost:8080/chat and send a few messages, the first one will be assigned as your username and any messages after that will be sent right back to you (and any other user connected to the WebSocket)

Making the WebSocket persistent on your server

Now we have a working websocket, the problem is, if we close the SSH or terminal session to the server the socket stops aswell. To get around this we can turn the WebSocket into a service. Navigate to /etc/init on your server and make a file called chatSocket.conf with the following contents

# Info
description "Runs the Chat Web Socket"  
author      "Your Name Here"

# Events
start on startup  
stop on shutdown

# Automatically respawn
respawn limit 20 5

# Run the script!
# Note, in this example, if your PHP script (the socket) returns
# the string "ERROR", the daemon will stop itself.
    [ $(exec /usr/bin/php -f /path/to/socket.php) = 'ERROR' ] && ( stop; exit 1; )
end script  

Now you will be able to run service chatSocket start and the WebSocket will run as a service even when you close your SSH / terminal session.

Expanding on this example

The core functions of this PHP implementation of a WebSocket server are quite simple you have the following core methods which you customize as you need:
onMessage, onOpen, onClose and onError.
You can also add your own private and public methods specific to your implementation if you want like our sendMessage() method.

If you want to add another app on the same WebSocket you can simply add it to another route in the socket.php file like so.

$app->route('/foo', new YourClassName, array('*'));`

Final thoughts

As you can see, this implementation of WebSockets is far from ideal. But... If your project is locked in to using PHP and you want to use WebSockets this is by far the easiest and most versatile way to go.