phrity/websocket PHP Library

repository·v3.8-main·Indexed 42 days ago

https://github.com/sirn-se/websocket-php

A WebSocket client and server library for PHP supporting both TCP (ws) and SSL (wss) connections. It provides a middleware-based architecture for handling HTTP handshakes and WebSocket messages, supporting both asynchronous event-driven listeners and synchronous request/response patterns. Key features include PSR-3 logger integration, PSR-7 compliance, and support for various message types including Text, Binary, Ping, Pong, and Close.

Tokens
29K
Snippets
100
Records
124
Agent score
52%

What's inside phrity/websocket

  1. Extend functionality using Middleware

    v3.8-main

    The library uses a middleware pattern to intercept and process various stages of the WebSocket lifecycle. You can implement WebSocket\Middleware\MiddlewareInterface to hook into:

    • HTTP Handshake: processHttpIncoming and processHttpOutgoing.
    • WebSocket Messages: processIncoming and processOutgoing.
    • Lifecycle Ticks: processTick (useful for periodic tasks like heartbeats).

    Common built-in middlewares include:

    • WebSocket\Middleware\CompressionExtension: For handling per-message compression.
    • WebSocket\Middleware\PingInterval: To automatically send pings.
    • WebSocket\Middleware\SubprotocolNegotiation: To handle WebSocket subprotocols.
  2. How to use the Configuration instance

    v3.8-main

    The WebSocket\Configuration class is used to configure Client, Server, and various worker classes. You can instantiate it with optional arguments or pass an existing instance to the constructors of the Client or Server classes.

    Both Client and Server provide convenience methods to get and set the configuration directly, as well as specific setters for individual configuration properties (like setLogger or setTimeout).

    // Create a configuration
    $configuration = new WebSocket\Configuration();
    
    // Provide Configuration in constructor
    $client = new WebSocket\Client(
        uri: $uri,
        configuration: $configuration,
    );
    
    $server = new WebSocket\Server(
        port: $port,
        ssl: $ssl,
        configuration: $configuration,
    );
    
    // Or use convenience methods on the client/server directly
    $client->setConfiguration($configuration);
    $configuration = $client->getConfiguration();
  3. Understand exception handling levels

    v3.8-main

    The library categorizes exceptions into different levels that dictate how the application responds:

    InterfaceException ExamplesBehavior
    MessageLevelInterfaceBadOpcodeException, ConnectionTimeoutExceptionCannot read/send message, but connection remains open.
    ConnectionLevelInterfaceConnectionClosedException, ConnectionFailureException, HandshakeExceptionCloses the connection.
    HandlerLevelInterfaceBadUriException, ClientException, RunnerException, ServerExceptionUnresolvable; exits the application.
    N/ACloseExceptionInitiates the close procedure.
    N/AReconnectExceptionCloses and reconnects (optionally with a new URI).
  4. How to hand over initiative in middleware stacks

    v3.8-main

    When writing middleware, you must use the provided stack objects (ProcessStack, ProcessHttpStack, or ProcessTickStack) to pass control to the next middleware in the chain. If you do not call the appropriate handle* method, the message or operation will be halted and not reach subsequent middlewares.

    Stack Methods:

    • handleIncoming(): Used in ProcessIncomingInterface to get the received Message.
    • handleOutgoing($message): Used in ProcessOutgoingInterface to forward a Message to be sent.
    • handleHttpIncoming(): Used in ProcessHttpIncomingInterface to get the received HTTP message.
    • handleHttpOutgoing($message): Used in ProcessHttpOutgoingInterface to forward an HTTP message to be sent.
    • handleTick(): Used in ProcessTickInterface to forward the Tick operation.
    // Get the received Message, possibly handled by other middlewares
    $message = $stack->handleIncoming();
    
    // Forward the Message to be sent, possibly handled by other middlewares
    $message = $stack->handleOutgoing($message);
    
    // Get the received HTTP request/response message, possibly handled by other middlewares
    $message = $stack->handleHttpIncoming();
    
    // Forward the HTTP request/response message to be sent, possibly handled by other middlewares
    $message = $stack->handleHttpOutgoing($message);
    
    // Forward the Tick operation, possibly handled by other middlewares
    $stack->handleTick();
  5. Use Middlewares for protocol compliance

    v3.8-main

    Middlewares extend the server's functionality during message exchange. The library provides two essential middlewares for standard WebSocket operability:

    • WebSocket\Middleware\CloseHandler: Automatically handles incoming and outgoing Close requests.
    • WebSocket\Middleware\PingResponder: Automatically responds to Ping messages with Pong messages.

    If these are not added, you must manually implement the logic to handle connection closing and ping/pong heartbeats.

    $server = new WebSocket\Server();
    $server
        ->addMiddleware(new WebSocket\Middleware\CloseHandler())
        ->addMiddleware(new WebSocket\Middleware\PingResponder());
  6. Receive messages in v2 (Client and Server)

    v3.8-main

    The way messages are received has changed significantly in 2.x:

    Client

    • The receive() method now always returns an instance of Message (such as Text, Binary, Ping, Pong, or Close). In 1.x, this was controlled by the return_obj option, but it is now the standard behavior.
    • Recommended approach: Use listener callback methods instead of manual polling with receive().

    Server

    • The Server no longer has a receive() method.
    • Required approach: You must use listener callback methods to handle incoming messages.
  7. Create your own custom middleware

    v3.8-main

    To extend the library with custom logic, you can implement your own middleware by implementing the relevant interfaces provided by the library. Custom middlewares can intercept and handle three main areas of operation:

    1. WebSocket message transfers: Intercepting data sent or received.
    2. HTTP handshake operations: Modifying or reacting to the initial connection upgrade.
    3. Tick operability: Handling periodic internal library tasks.
  8. Use CompressionExtension middleware for message compression

    v3.8-main

    The CompressionExtension middleware adds support for message compression to your WebSocket client or server. You enable compression by passing one or more compressor instances as arguments to the CompressionExtension constructor.

    Negotiation Logic:

    • Client: Requests compression methods in the order they were added to the middleware.
    • Server: Responds with the first compression method it supports from the client's list.
    • Fallback: If the client and server cannot agree on a method, messages will be sent without compression.
    $client_or_server->addMiddleware(new WebSocket\Middleware\CompressionExtension(
        new WebSocket\Middleware\CompressionExtension\DeflateCompressor()
    ));
  9. Use the PingInterval middleware for heartbeats

    v3.8-main

    The PingInterval middleware provides heartbeat functionality by sending Ping messages at a specified interval. This is typically used to keep connections alive and prevent them from being closed due to inactivity.

    Key Behaviors:

    • If no interval is specified, the middleware defaults to using the connection's timeout configuration as the interval.
    • Important: You should generally set the interval to a value lower than your core connection timeout configuration. If the runner is blocked for the duration of the timeout, the PingInterval might not execute until the connection has already been considered timed out.

    To use it, add the middleware to your client or server instance using addMiddleware().

    $client_or_server->addMiddleware(new WebSocket\Middleware\PingInterval(interval: 10));
  10. Use the CloseHandler middleware for standard WebSocket close handling

    v3.8-main

    The CloseHandler middleware implements the standard WebSocket protocol behavior for closing connections. You should add this middleware to your client or server instance unless you are providing a custom implementation of close handling.

    It manages the following lifecycle events:

    • Receiving a Close message: Automatically responds with a Close confirmation message.
    • Receiving a Close confirmation message: Automatically closes the connection.
    • Sending a Close message: Blocks any further messages from being sent on that connection to ensure protocol compliance.
    $client_or_server->addMiddleware(new WebSocket\Middleware\CloseHandler());