puff/websocket-server

Fiber-based WebSocket application for PHP Unison Fiber Framework

Maintainers

Package info

github.com/php-puff/websocket-server

pkg:composer/puff/websocket-server

Transparency log

Statistics

Installs: 0

Dependents: 0

Suggesters: 0

Stars: 0

Open Issues: 0

dev-main 2026-08-28 10:58 UTC

This package is auto-updated.

Last update: 2026-08-28 10:59:33 UTC


README

Fiber-based RFC 6455 WebSocket server for Puff. It reuses puff/server for non-blocking TCP I/O and provides strict handshakes, masked frame parsing, fragmentation, Ping/Pong, graceful close frames and ordered per-connection message handling. Composer discovery mounts Puff\WebsocketServer\WebSocketApplication automatically.

$app = new Puff\Application\Application($config);
$app->run(); // Starts every installed application on one shared event loop.

The package publishes config/websocket.server.php; its values are available under websocket.server. The default endpoint is ws://127.0.0.1:8791. Incoming messages are echoed unless handler or routes is configured.

return [
    'addr' => '127.0.0.1:8791',
    'routes' => dirname(__DIR__) . '/app/websocket.php',
    'workers' => 1,
    'max_message_size' => 2 * 1024 * 1024,
    'max_handshake_size' => 16 * 1024,
    'max_headers' => 100,
    'max_pending_messages' => 128,
    'allowed_origins' => ['https://example.com'],
    'protocols' => ['json'],
];

An empty allowed_origins list accepts any syntactically valid Origin. Configure an explicit list for browser-facing production services. Messages from one connection run sequentially; separate connections can run concurrently.

Routes are grouped by handshake path and then by message event:

return [
    '/chat' => [
        'events' => [
            'message.send' => [ChatController::class, 'send'],
        ],
        'lifecycle' => [
            'open' => [ChatController::class, 'open'],
            'close' => [ChatController::class, 'close'],
        ],
    ],
    '*' => [
        'events' => [
            'ping' => [SystemController::class, 'ping'],
        ],
    ],
];

Clients send JSON messages such as {"event":"message.send","data":{"message":"Hello"}}. Controller arguments are resolved by the application container. The following values are injectable by name or type:

  • data, event, and path
  • Handshake $handshake
  • headers, query, and cookies
  • Connection $connection
  • Server $server

Arrays and objects returned by controllers are encoded as JSON. Event routing accepts text JSON frames; use a custom HandlerInterface for binary protocols.

Custom handler

Implement HandlerInterface when the connection lifecycle or binary frames require direct control:

use Puff\Server\Connection;
use Puff\WebsocketServer\Frame;
use Puff\WebsocketServer\Handshake;
use Puff\WebsocketServer\HandlerInterface;
use Puff\WebsocketServer\Server;

final class SocketHandler implements HandlerInterface
{
    public function open(Handshake $handshake, Connection $connection, Server $server): mixed
    {
        return null;
    }

    public function message(
        Handshake $handshake,
        string $payload,
        int $opcode,
        Connection $connection,
        Server $server,
    ): mixed {
        return $opcode === Frame::BINARY ? $payload : strtoupper($payload);
    }

    public function close(Handshake $handshake, Connection $connection, Server $server): void
    {
    }
}

Throw HandshakeException from open() to reject a connection before the 101 Switching Protocols response.