Créer un serveur WebSocket en PHP

Les WebSockets sont une technologie de communication récente qui permet une communication en temps réel entre un navigateur web et un serveur. Cet article vous montrera comment créer un serveur WebSocket en PHP en utilisant la bibliothèque Ratchet.

Prérequis

  • Un serveur web exécutant PHP 7.0 ou supérieur
  • La bibliothèque Ratchet, qui peut être installée en utilisant Composer : composer require cboden/ratchet

Mise en place du serveur

Pour créer un serveur WebSocket en PHP, nous allons utiliser la classe Ratchet\Server\IoServer de la bibliothèque Ratchet.

server.php
<?php
require 'vendor/autoload.php';

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

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

$server->run();

Dans cet exemple, nous créons un objet IoServer en utilisant la méthode factory, en lui passant en paramètre un objet HttpServer qui contient un objet WsServer qui contient enfin un objet de notre propre classe Chat, qui gère les connexions et les échanges de messages. Le serveur écoutera sur le port 8080.

MyApp\Chat
<?php
namespace MyApp;

use Ratchet\ConnectionInterface;
use Ratchet\MessageComponentInterface;

class Chat implements MessageComponentInterface
{
    protected $clients;

    public function __construct() {
        $this->clients = new \SplObjectStorage;
    }

    public function onOpen(ConnectionInterface $conn) {
        $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) {
                $client->send($msg);
            }
        }
    }

    public function onClose(ConnectionInterface $conn) {
        $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();
    }
}

La classe Chat utilise la SplObjectStorage pour stocker les connexions en cours. Les méthodes onOpen, onMessage, onClose et onError sont appelées respectivement lorsqu’une connexion est établie, lorsqu’un message est reçu, lorsqu’une connexion est fermée et lorsqu’une erreur se produit. Dans cette classe, lorsqu’un message est reçu, il est envoyé à tous les clients connectés sauf celui qui l’a envoyé.

Cette classe est un exemple de base, pour l’améliorer, il faudra mettre en place des vérifications et des gestions d’erreurs.

Démarer le serveur

Pour démarrer un serveur WebSocket en PHP, vous pouvez utiliser la commande suivante dans votre terminal :

php path/to/server.php

path/to/server.php est le chemin vers le fichier contenant votre code pour créer et lancer le serveur (comme indiqué dans l’exemple que je vous ai donné).

Connexion d'un client

Pour se connecter à un serveur WebSocket en PHP, nous pouvons utiliser la fonction WebSocket.connect() en JavaScript.

client.js
var conn = new WebSocket('ws://localhost:8080');
conn.onopen = function(e) {
    console.log("Connection established!");
};
conn.onmessage = function(e) {
    console.log(e.data);
};

Nous créons un nouvel objet WebSocket en lui passant en paramètre l’URL du serveur, ici ws://localhost:8080. Nous définissons ensuite des fonctions pour gérer les événements onopen et onmessage, qui sont déclenchés lorsque la connexion est établie et lorsque des messages sont reçus.

Envoi de messages

Pour envoyer un message à travers une connexion WebSocket en PHP, nous pouvons utiliser la méthode send() de l’objet WebSocket côté client, et la méthode send() de la classe ConnectionInterface côté serveur.

client.js
// Côté client
conn.send("Hello, server!");
server.php
// Côté serveur
$client->send("Hello, client!");

Côté client, nous utilisons la méthode send() de l’objet WebSocket pour envoyer le message « Hello, server! » au serveur. Côté serveur, nous utilisons la méthode send() de la classe ConnectionInterface pour envoyer le message « Hello, client! » au client connecté.

La méthode send() peut être utilisée pour envoyer des données sous différents format (texte, binaire, JSON, …) en fonction de la nécessité.

Il est aussi possible de broadcast des messages à tous les clients connectés en utilisant la méthode broadcast() de la classe IoServer.

server.php
<?php
$server->broadcast("New message for all connected clients!");

En utilisant cette méthode, tous les clients connectés au serveur WebSocket PHP recevront le message « New message for all connected clients! ».

Avec ces quelques lignes de codes, vous avez maintenant toutes les informations nécessaires pour créer un serveur WebSocket en PHP, gérer les connexions et les échanges de messages. N’oubliez pas de mettre en place des vérifications et des gestions d’erreurs pour une utilisation en production.

Si vous êtes intéressez par des articles sur les websockets, j’ai fais un tutoriel sur comment créer un chat en ligne en javascript.

Newsletter

Ne manquez jamais les nouveaux conseils, tutoriels et autres.

Pas de spam, jamais. Nous ne partagerons jamais votre adresse électronique et vous pouvez vous désabonner à tout moment.