Learning Management Platform for Written Tutorial Series.

WebSocket Server PHP

WebSocket Server PHP

Introduction

This tutorial serves as a basic introduction to Websocket server programming using PHP. We will use an open source web socket server library Ratchet found at http://socketo.me/ . The web socket library will provide the base functionality for creating our own Websocket server. Ratchet Supports the RFC6455, HyBi-10+, and Hixie76 protocol versions (at the same time). We will build a server for a real-time chatting application.

Topics covered

  • Requirements for developing the Websocket server in PHP
  • Installing Composer
  • Installing Ratchet
  • Creating a chat WebSocket server
  • Testing the Websocket server with a client application

By the end of this tutorial, you should be able to develop a basic Websocket server in PHP. The web server should be able to respond to client requests.

We will use PHP to build the server. This tutorial assumes you are familiar with;

  • PHP
  • Object oriented programming and the general concept of namespaces in PHP.
  • You have a web server such as WAMP or XAMPP.

We will use XAMPP on windows; however, the tutorial should still work on other platforms with PHP, a web server and web browsers that support HTML 5.

Downloading and installing Composer

Ratchet users composer, composer is a dependency management tool for PHP. For more details on how to download and install composer, check this link https://getcomposer.org/doc/00-intro.md

Downloading and installing Ratchet

Create a folder in your web root called wsserver

Create a file composer.json in your web server root.

Add the following code to composer.json

{
    "autoload": {
        "psr-0": {
            "MyApp": "src"
        }
    },
    "require": {
        "cboden/Ratchet": "0.3.*"
    }
}

HERE,

  • "autoload" is a composer feature that implements PSR-0. PSR-0 is a recommended standard for autoloading libraries as opposed to using require statements. Check this link for more details. https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-0.md
  • "MyApp" : "src" specifies MyApp as the namespace while src specifies the library’s location.
  • "require" tells composer to load cboden/Ratchet version 0.3.* and all the dependencies that it uses.

Installing Ratchet and its dependencies

Open the command prompt, Note: we are using windows for this tutorial Type the following command then press enter key

cd c://xampp/htdocs/wsserver

you will get the following results

FireFox Browser WebSocket Support

Type the following command then press enter key

composer install

you will get the following results FireFox Browser WebSocket Support

  1. Create a new folder called bin in wsserver folder
  2. Create a new folder called src in wsserver folder
  3. Create a sub folder called MyApp in src folder

You should have a folder structure as shown below in the image

FireFox Browser WebSocket Support

We will now create the main Chat class. This class will implement the WebSocket server events

Create a new file named Chat.php in src/MyApp/Chat.php

Add the following code

<?php

namespace MyApp;

use Ratchet\MessageComponentInterface;
use Ratchet\ConnectionInterface;
class Chat implements MessageComponentInterface {

}

HERE,

  • namespace MyApp; declares the namespace MyApp, remember we used composer to autoload libraries in MyApp namespace during installation
  • use Ratchet\ MessageComponentInterface\ ConnectionInterface imports the Message Component and Connection interfaces from the Ratchet namespace.
  • class Chat implements MessageComponentInterfaceimplements the Message Component interface.

Let’s now add some logic to our class

Add the following instance variable and class constructor

protected $clients;

public function __construct() {
    $this->clients = new \SplObjectStorage;
    echo "Congratulations! the server is now running\n";
}

HERE,

  • protected $clients; is the instance variable that will be used to store active client connections to the server
  • $this->clients = new \SplObjectStorage initializes the variable $this->clients to SplObjectStorage

Add the following functions to the class

public function onOpen(ConnectionInterface $conn) {
    // Store the new connection to send messages to later
    $this->clients->attach($conn);

    echo "New connection! ({$conn->resourceId})\n";
}

public function onMessage(ConnectionInterface $from, $msg) {
    $numRecv = count($this->clients) - 1;
    echo sprintf('Connection %d sending message "%s" to %d other connection%s' . "\n"
            , $from->resourceId, $msg, $numRecv, $numRecv == 1 ? '' : 's');

    foreach ($this->clients as $client) {
        if ($from !== $client) {
            // The sender is not the receiver, send to each client connected
            $client->send($msg);
        }
    }
}

public function onClose(ConnectionInterface $conn) {
    // The connection is closed, remove it, as we can no longer send it messages
    $this->clients->detach($conn);

    echo "Connection {$conn->resourceId} has disconnected\n";
}

public function onError(ConnectionInterface $conn, \Exception $e) {
    echo "An error has occurred: {$e->getMessage()}\n";

    $conn->close();
}

HERE,

  • onOpen implements the onopen event of the WebSocket server. It stores the connection to the $clients variable then echos the connection to the console. We will get to the console later on.
  • onMessage implements the onmessage event of the WebSocket server. Once a message has being received, it is sent to all the active connections except where the message is coming from
  • onClose implements the onclose event of the WebSocket. It disconnects a client connect and removes it from the storage object.
  • onError implements the onerror event of the WebSocket. This method is called whenever an error occurs and displays it on the console.

That is it for the application logic. The complete source code for the Chat.php file should be as follows

<?php

namespace MyApp;

use Ratchet\MessageComponentInterface;
use Ratchet\ConnectionInterface;

class Chat implements MessageComponentInterface {

    protected $clients;

    public function __construct() {
        $this->clients = new \SplObjectStorage;
        echo "Congratulations! the server is now running\n";
    }

    public function onOpen(ConnectionInterface $conn) {
        // Store the new connection to send messages to later
        $this->clients->attach($conn);

        echo "New connection! ({$conn->resourceId})\n";
    }

    public function onMessage(ConnectionInterface $from, $msg) {
        $numRecv = count($this->clients) - 1;
        echo sprintf('Connection %d sending message "%s" to %d other connection%s' . "\n"
                , $from->resourceId, $msg, $numRecv, $numRecv == 1 ? '' : 's');

        foreach ($this->clients as $client) {
            if ($from !== $client) {
                // The sender is not the receiver, send to each client connected
                $client->send($msg);
            }
        }
    }

    public function onClose(ConnectionInterface $conn) {
        // The connection is closed, remove it, as we can no longer send it messages
        $this->clients->detach($conn);

        echo "Connection {$conn->resourceId} has disconnected\n";
    }

    public function onError(ConnectionInterface $conn, \Exception $e) {
        echo "An error has occurred: {$e->getMessage()}\n";

        $conn->close();
    }

}

We will now have to create a chat server that uses the above application logic

Create a new file named chat-server.php in bin/chat-server.php

Add the following lines of code

<?php

use Ratchet\Server\IoServer;
use Ratchet\Http\HttpServer;
use Ratchet\WebSocket\WsServer;
use MyApp\Chat;

require dirname(__DIR__) . '/vendor/autoload.php';

$server = IoServer::factory(
                new HttpServer(
                new WsServer(
                new Chat()
                )
                ), 999
);

$server->run();

Running the WebSocket server

The server is a daemon, we will not open http://loclahost/wsserver/bin/chat-server.php to run it. we will use a command to run it.

Browser to the location c://xampp/htdocs/wsserver/bin or whatever location that you saved the files in.

Type the following command then press enter key

php chat-server.php

you will get the following results

FireFox Browser WebSocket Support

In the next tutorial, we will create a client application that communicates with the server.

Tutorial History

Tutorial version 1: Date Published 2015-08-20


...