lexty/websocketserver

A WebSocket implementation for PHP 5.4

v0.1.2+1 2015-09-22 09:37 UTC

This package is not auto-updated.

Last update: 2024-11-09 18:54:07 UTC


README

A WebSocket implementation for PHP. Supports RFC6455.

Requirements

Installation

Using Composer:

composer require lexty/websocketserver

A quick example

<?php

use Lexty\WebSocketServer\Server;
use Lexty\WebSocketServer\BaseApplication;

// Make sure composer dependencies have been installed
require __DIR__ . '/vendor/autoload.php';

/**
 * chat.php
 * Send any incoming messages to all connected clients
 */
class Chat extends BaseApplication 
{
    private $clients;

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

    public function onOpen(ConnectionInterface $conn, HandlerInterface $handler)
    {
        $this->clients->attach($conn);
    }

    public function onMessage(ConnectionInterface $from, PayloadInterface $msg, HandlerInterface $handler)
    {
        if (!$msg->checkEncoding('utf-8')) {
            return;
        }
        $message = 'user #' . $from->id . ' (' . $handler->pid . '): ' . strip_tags($msg);

        foreach ($this->clients as $client) {
            $client->send($message);
        }
    }

    public function onClose(ConnectionInterface $conn = null, HandlerInterface $handler)
    {
        $this->clients->detach($conn);
    }
}

$server = new Server('0.0.0.0', 8080, '/tmp/web-socket-server.pid');
$server
    ->registerApplication('/chat', new Chat)
    ->run();
$ php chat.php
// Then some JavaScript in the browser:
var conn = new WebSocket('ws://localhost:8080/chat');
conn.onmessage = function(e) { console.log(e.data); };
conn.send('Hello Me!');

You can pass additional parameters in the server connection. For example, for authorization.

// In the browser:
var conn = new WebSocket('ws://localhost:8080/chat?user=login&auth=token');
<?php

use Lexty\WebSocketServer\BaseApplication;

class App extends BaseApplication 
{
    public function onOpen(ConnectionInterface $conn, HandlerInterface $handler)
    {
        $user = $conn->request->query['user'];
        $auth = $conn->request->query['auth'];
        if (!$user || !$auth) { // some authorization
            $conn->close();
        }
    }
}

Override library classes

For using your own implementation of classes Connection or Payload you should override they names in DI container.

<?php
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Lexty\WebSocketServer\Applications\Chat;

$container = new ContainerBuilder;
// MyConnectionClass must implements ConnectionInterface
$container->setParameter('lexty.websocketserver.payload.class', 'MyConnectionClass');
// MyPayloadClass must implements PayloadInterface
$container->setParameter('lexty.websocketserver.connection.class', 'MyPayloadClass');

$server = new Server('localhost', 8080, '/tmp/websocketserver.pid', 1, $container)
    ->registerApplication('/chat', new Chat)
    ->run();