### Clone and Install Ratchet Examples Source: https://github.com/ratchetphp/ratchet/wiki/"Hello-World"-in-5-minutes Use these bash commands to clone the Ratchet examples repository and install its dependencies using Composer. ```bash git clone git://github.com/cboden/Ratchet-examples.git cd Ratchet-examples composer.phar install php bin/logged-terminal-chat.php ``` -------------------------------- ### Start Ratchet\Server\IoServer with Factory Shortcut Source: https://context7.com/ratchetphp/ratchet/llms.txt This is a convenience constructor for IoServer that automatically creates the ReactPHP event loop and socket server. It's a quick way to get a WebSocket server running. ```php run(); ``` -------------------------------- ### PHP WebSocket Chat Server Example Source: https://github.com/ratchetphp/ratchet/blob/0.4.x/README.md This example demonstrates a basic chat application using Ratchet. It requires Composer dependencies to be installed. The server listens on port 8080 and routes '/chat' to a custom chat component and '/echo' to a built-in echo server. ```php clients = new \SplObjectStorage; } public function onOpen(ConnectionInterface $conn) { $this->clients->attach($conn); } public function onMessage(ConnectionInterface $from, $msg) { foreach ($this->clients as $client) { if ($from != $client) { $client->send($msg); } } } public function onClose(ConnectionInterface $conn) { $this->clients->detach($conn); } public function onError(ConnectionInterface $conn, \Exception $e) { $conn->close(); } } // Run the server application through the WebSocket protocol on port 8080 $app = new Ratchet\App('localhost', 8080); $app->route('/chat', new MyChat, array('*')); $app->route('/echo', new Ratchet\Server\EchoServer, array('*')); $app->run(); ``` ```bash $ php chat.php ``` -------------------------------- ### Browser WebSocket Client Example Source: https://context7.com/ratchetphp/ratchet/llms.txt A basic JavaScript client for connecting to a Ratchet WebSocket server. This example shows how to establish a connection, send a JSON message upon opening, and log received messages and connection closures. ```javascript // Browser client var conn = new WebSocket('ws://localhost:8080/chat'); conn.onopen = () => conn.send(JSON.stringify({ user: 'Alice', text: 'Hello!' })); conn.onmessage = e => console.log('Received:', e.data); conn.onclose = () => console.log('Disconnected'); ``` -------------------------------- ### Start Ratchet\Server\IoServer with Manual Construction Source: https://context7.com/ratchetphp/ratchet/llms.txt This method shows how to manually construct the IoServer using a pre-existing ReactPHP event loop and socket server. It allows for more control, such as adding periodic timers before running the server. ```php addPeriodicTimer(60, function () { echo "Server heartbeat — " . date('H:i:s') . "\n"; }); $server->run(); // Public properties available after construction: // $server->loop — React\EventLoop\LoopInterface // $server->app — the root MessageComponentInterface // $server->socket — React\Socket\ServerInterface ``` -------------------------------- ### Install Ratchet via Composer Source: https://github.com/ratchetphp/ratchet/blob/0.4.x/README.md This command installs the Ratchet library using Composer. It ensures that all necessary dependencies are downloaded and configured for your project. ```bash composer require cboden/ratchet:^0.4.4 ``` -------------------------------- ### Implement WAMP Server with Ratchet Source: https://context7.com/ratchetphp/ratchet/llms.txt Implement the `WampServerInterface` to handle WAMP events. This example shows how to manage subscriptions, publications, and RPC calls within a `StockTicker` class. ```php resourceId} subscribed to {$topic}\n"; } // Called when a client unsubscribes public function onUnSubscribe(ConnectionInterface $conn, $topic): void { echo "{$conn->resourceId} left {$topic}\n"; } // Called when a client publishes to a topic public function onPublish(ConnectionInterface $conn, $topic, $event, array $exclude, array $eligible): void { // $topic->broadcast() sends to ALL subscribers, respecting exclude/eligible lists $topic->broadcast($event, $exclude, $eligible); } // Called for Remote Procedure Calls public function onCall(ConnectionInterface $conn, $id, $topic, array $params): void { if ((string)$topic === 'http://example.com/api#getPrice') { $price = 42.00; // fetch from DB $conn->callResult($id, ['price' => $price]); // respond to RPC caller } else { $conn->callError($id, $topic, 'Unknown procedure'); } } public function onOpen(ConnectionInterface $conn): void {} public function onClose(ConnectionInterface $conn): void {} public function onError(ConnectionInterface $conn, \Exception $e): void { $conn->close(); } } // Wire up: WampServer decorates your WampServerInterface impl, WsServer handles WebSocket protocol $app = new Ratchet\App('localhost', 8080); $app->route('/ticker', new StockTicker, ['*']); $app->run(); ``` -------------------------------- ### Manage Pub/Sub Topics with Ratchet\Wamp\Topic Source: https://context7.com/ratchetphp/ratchet/llms.txt Utilize the `Ratchet\Wamp\Topic` class to manage subscribers and broadcast messages. This example shows how to get topic information, broadcast messages with exclusions, and iterate over subscribers. ```php getId() . "\n"; // e.g. "http://example.com/chat" echo "Subscriber count: " . count($topic) . "\n"; // implements Countable // Broadcast to all subscribers except those in $exclude, restricted to $eligible if set $topic->broadcast( ['message' => $event, 'from' => $conn->WAMP->sessionId], $exclude, // array of WAMP session IDs to skip $eligible // array of WAMP session IDs to exclusively target (empty = all) ); // Check if a specific connection is subscribed if ($topic->has($conn)) { echo "Publisher is also a subscriber\n"; } // Iterate over all subscribers manually foreach ($topic as $subscriber) { if ($subscriber !== $conn) { $subscriber->event($topic->getId(), ['ping' => true]); } } // Topic::add() and Topic::remove() are called by TopicManager automatically, // but can be used if managing topics manually (bypassing WampServer): // $topic->add($conn); // $topic->remove($conn); } ``` -------------------------------- ### Install Ratchet via Composer Source: https://context7.com/ratchetphp/ratchet/llms.txt Install the Ratchet library using Composer. This command requires PHP version 5.4.2 or higher. ```bash composer require cboden/ratchet:^0.4.4 ``` -------------------------------- ### Chat Server Implementation with Ratchet App Source: https://context7.com/ratchetphp/ratchet/llms.txt Implement a chat server using Ratchet's high-level App facade. This example demonstrates handling new connections, broadcasting messages to all clients except the sender, and managing disconnections and errors. It uses the `MessageComponentInterface` to define server logic. ```php clients = new \SplObjectStorage; } public function onOpen(ConnectionInterface $conn): void { $this->clients->attach($conn); echo "New connection: {$conn->resourceId}\n"; } public function onMessage(ConnectionInterface $from, $msg): void { foreach ($this->clients as $client) { if ($client !== $from) { $client->send($msg); // broadcast to all other clients } } } public function onClose(ConnectionInterface $conn): void { $this->clients->detach($conn); echo "Connection {$conn->resourceId} disconnected\n"; } public function onError(ConnectionInterface $conn, \Exception $e): void { echo "Error: {$e->getMessage()}\n"; $conn->close(); } } // App($httpHost, $port, $address, $loop) // $address '127.0.0.1' = proxy-only; '0.0.0.0' = accept from any interface $app = new Ratchet\App('localhost', 8080, '0.0.0.0'); // route($path, $controller, $allowedOrigins, $httpHost) // ['*'] disables same-origin enforcement; default restricts to $httpHost $app->route('/chat', new ChatServer, ['*']); $app->route('/echo', new Ratchet\Server\EchoServer, ['*']); $app->run(); // enters the ReactPHP event loop; blocks until process is killed ``` -------------------------------- ### Implement Ratchet\MessageComponentInterface for Chat Rooms Source: https://context7.com/ratchetphp/ratchet/llms.txt This example demonstrates using MessageComponentInterface to manage connections within different chat rooms. It utilizes SplObjectStorage for efficient client management and accesses PSR-7 request details. ```php clients = new \SplObjectStorage; } public function onOpen(ConnectionInterface $conn): void { $this->clients->attach($conn); // Built-in properties $id = $conn->resourceId; // (int) unique ID derived from stream resource $ip = $conn->remoteAddress; // (string) client IP, e.g. "192.168.1.42" // PSR-7 request available after WsServer/HttpServer layer $path = $conn->httpRequest->getUri()->getPath(); // e.g. "/chat" $qs = $conn->httpRequest->getUri()->getQuery(); // e.g. "room=general" parse_str($qs, $params); $conn->room = $params['room'] ?? 'default'; // store arbitrary data on the connection $conn->send(json_encode(['event' => 'welcome', 'room' => $conn->room])); } public function onMessage(ConnectionInterface $from, $msg): void { foreach ($this->clients as $client) { if ($client->room === $from->room && $client !== $from) { $client->send($msg); } } } public function onClose(ConnectionInterface $conn): void { $this->clients->detach($conn); } public function onError(ConnectionInterface $conn, \Exception $e): void { $conn->close(); } } ``` -------------------------------- ### Connect to WAMP Server with autobahn.js Source: https://context7.com/ratchetphp/ratchet/llms.txt Connect to a Ratchet WAMP server using the autobahn.js client library in a browser. This example demonstrates subscribing to a topic and making an RPC call. ```javascript // Browser using autobahn.js WAMP client var conn = new autobahn.Connection({ url: 'ws://localhost:8080/ticker', realm: 'realm1' }); conn.onopen = function(session) { // Subscribe session.subscribe('http://example.com/stocks/AAPL', function(args) { console.log('Price update:', args[0]); }); // RPC call session.call('http://example.com/api#getPrice', ['AAPL']).then(function(res) { console.log('Current price:', res.price); }); }; conn.open(); ``` -------------------------------- ### JavaScript WebSocket Client Example Source: https://github.com/ratchetphp/ratchet/blob/0.4.x/README.md This JavaScript code connects to a Ratchet WebSocket server running on ws://localhost:8080/echo. It logs received messages to the console and sends 'Hello Me!' upon connection. ```javascript // Then some JavaScript in the browser: var conn = new WebSocket('ws://localhost:8080/echo'); conn.onmessage = function(e) { console.log(e.data); }; conn.onopen = function(e) { conn.send('Hello Me!'); }; ``` -------------------------------- ### Configure and Run Flash Policy Server Source: https://context7.com/ratchetphp/ratchet/llms.txt Instantiate `FlashPolicy`, add allowed access rules for domains and ports, optionally set site control, and render the policy XML. This snippet also shows how to validate domain/port rules and run the server on the standard Flash policy port. ```php addAllowedAccess('myapp.com', '8080'); // specific port $policy->addAllowedAccess('myapp.com', '8080-8090'); // port range $policy->addAllowedAccess('*.myapp.com','*'); // wildcard subdomain, all ports $policy->addAllowedAccess('*', '80,443'); // any domain, ports 80 and 443 // Optional: restrict which policy files Flash will accept from this domain $policy->setSiteControl('master-only'); // 'none' | 'master-only' | 'all' // Preview the generated XML echo $policy->renderPolicy()->asXML(); // // // // // ... // // Validate before adding (returns bool) var_dump($policy->validateDomain('*.myapp.com')); // true var_dump($policy->validatePorts('8080-8090')); // true // Run on the standard Flash policy port (requires root on Linux) $server = IoServer::factory($policy, 843, '0.0.0.0'); $server->run(); ``` -------------------------------- ### Implement WebSocket Server with WsServer Source: https://context7.com/ratchetphp/ratchet/llms.txt Wraps a MessageComponentInterface application with WebSocket handshake and framing. Enable keep-alive pings to manage client responsiveness. Must be placed inside an HttpServer. ```php isBinary()) { // handle binary frame (e.g., image upload, audio chunk) $conn->send($msg); // echo binary back } else { $conn->send(strtoupper($msg->getPayload())); } } public function onOpen(\Ratchet\ConnectionInterface $conn): void {} public function onClose(\Ratchet\ConnectionInterface $conn): void {} public function onError(\Ratchet\ConnectionInterface $conn, \Exception $e): void { $conn->close(); } } $wsServer = new WsServer(new BinaryHandler); // Enable keep-alive: ping all clients every 30 s; close unresponsive ones $loop = \React\EventLoop\Loop::get(); $wsServer->enableKeepAlive($loop, 30); // $interval in seconds $socket = new \React\Socket\SocketServer('0.0.0.0:8080', [], $loop); $server = new IoServer(new HttpServer($wsServer), $socket, $loop); $server->run(); ``` -------------------------------- ### FlashPolicy Server Configuration and Usage Source: https://context7.com/ratchetphp/ratchet/llms.txt This snippet demonstrates how to instantiate and configure the FlashPolicy server, add allowed access rules, set site control, render the policy XML, validate domains and ports, and run the server on the standard Flash policy port. ```APIDOC ## `Ratchet\Server\FlashPolicy` Serves Adobe Flash cross-domain policy files on port 843 (or 843 in dev), required by Flash-based WebSocket polyfills on older browsers. Automatically configured by `App`, but can be run as a standalone server. ### Methods * **`addAllowedAccess(string $domain, string $ports, bool $secure = false)`**: Adds an allowed access rule for a specific domain and ports. * `$domain`: The domain to allow access from (e.g., 'myapp.com', '*.myapp.com', '*'). * `$ports`: The ports or port ranges allowed (e.g., '8080', '8080-8090', '*'). * `$secure`: Whether the connection should be secure (defaults to false). * **`setSiteControl(string $control)`**: Restricts which policy files Flash will accept from this domain. * `$control`: Can be 'none', 'master-only', or 'all'. * **`renderPolicy()`**: Renders the generated policy XML. * Returns an XML object. * **`validateDomain(string $domain)`**: Validates if a given domain matches the allowed access rules. * Returns `bool`. * **`validatePorts(string $ports)`**: Validates if a given port string is valid. * Returns `bool`. ### Running the Server To run the FlashPolicy server on the standard port (843): ```php use Ratchet\Server\IoServer; use Ratchet\Server\FlashPolicy; $policy = new FlashPolicy; // Add access rules $policy->addAllowedAccess('myapp.com', '8080'); $policy->addAllowedAccess('myapp.com', '8080-8090'); $policy->addAllowedAccess('*.myapp.com','*'); $policy->addAllowedAccess('*', '80,443'); // Set site control (optional) $policy->setSiteControl('master-only'); // Render and echo the policy XML (for preview) echo $policy->renderPolicy()->asXML(); // Validate domain and ports (optional) var_dump($policy->validateDomain('*.myapp.com')); var_dump($policy->validatePorts('8080-8090')); // Run the server on port 843 $server = IoServer::factory($policy, 843, '0.0.0.0'); $server->run(); ``` **Note**: Running on port 843 may require root privileges on Linux. ``` -------------------------------- ### Ratchet\WebSocket\WsServer Source: https://context7.com/ratchetphp/ratchet/llms.txt Wraps a MessageComponentInterface or WebSocket\MessageComponentInterface application with RFC 6455 WebSocket handshake negotiation, framing, and keep-alive ping/pong management. Must be placed inside an HttpServer in manual stacks. ```APIDOC ## `Ratchet\WebSocket\WsServer` — WebSocket Protocol Handler Wraps a `MessageComponentInterface` or `WebSocket\MessageComponentInterface` application with RFC 6455 WebSocket handshake negotiation, framing, and keep-alive ping/pong management. Must be placed inside an `HttpServer` in manual stacks. ### Enable Keep-Alive ```php // Enable keep-alive: ping all clients every 30 s; close unresponsive ones $loop = \React\EventLoop\Loop::get(); $wsServer->enableKeepAlive($loop, 30); // $interval in seconds ``` ### Example Usage ```php isBinary()) { // handle binary frame (e.g., image upload, audio chunk) $conn->send($msg); // echo binary back } else { $conn->send(strtoupper($msg->getPayload())); } } public function onOpen(\Ratchet\ConnectionInterface $conn): void {} public function onClose(\Ratchet\ConnectionInterface $conn): void {} public function onError(\Ratchet\ConnectionInterface $conn, \Exception $e): void { $conn->close(); } } $wsServer = new WsServer(new BinaryHandler); // Enable keep-alive: ping all clients every 30 s; close unresponsive ones $loop = \React\EventLoop\Loop::get(); $wsServer->enableKeepAlive($loop, 30); // $interval in seconds $socket = new \React\Socket\SocketServer('0.0.0.0:8080', [], $loop); $server = new IoServer(new HttpServer($wsServer), $socket, $loop); $server->run(); ?> ``` ``` -------------------------------- ### Block IPs with Ratchet\Server\IpBlackList Source: https://context7.com/ratchetphp/ratchet/llms.txt Use IpBlackList to decorate a MessageComponentInterface and block connections from specified IP addresses. Connections from blocked IPs are closed immediately in onOpen. ```php blockAddress('192.168.1.100'); $blacklist->blockAddress('10.0.0.55'); // Introspection var_dump($blacklist->isBlocked('192.168.1.100')); // bool(true) var_dump($blacklist->isBlocked('192.168.1.200')); // bool(false) print_r($blacklist->getBlockedAddresses()); // ['192.168.1.100', '10.0.0.55'] // Unblock later (e.g., after a ban expires) $blacklist->unblockAddress('10.0.0.55'); // IpBlackList is a MessageComponentInterface, so wrap it in the WS stack normally $server = IoServer::factory( new HttpServer(new WsServer($blacklist)), 8080, '0.0.0.0' ); $server->run(); ``` -------------------------------- ### Connect to the Chat Server Source: https://github.com/ratchetphp/ratchet/wiki/"Hello-World"-in-5-minutes Connect to the running Ratchet chat server using telnet on localhost port 8000. Any messages entered will be broadcast to other connected clients. ```bash telnet localhost 8000 ``` -------------------------------- ### Implement Ratchet\MessageComponentInterface for Notifications Source: https://context7.com/ratchetphp/ratchet/llms.txt Implement this interface to handle WebSocket connections and messages. It combines onOpen, onClose, onError, and onMessage callbacks. Use when message payloads are raw strings. ```php [conn, ...] public function onOpen(ConnectionInterface $conn): void { // $conn->resourceId — unique integer ID for this connection // $conn->remoteAddress — client IP address echo "Client {$conn->resourceId} connected from {$conn->remoteAddress}\n"; } public function onMessage(ConnectionInterface $from, $msg): void { $data = json_decode($msg, true); if ($data['action'] === 'subscribe') { $this->subscriptions[$data['topic']][] = $from; $from->send(json_encode(['status' => 'subscribed', 'topic' => $data['topic']])); } elseif ($data['action'] === 'publish') { foreach (($this->subscriptions[$data['topic']] ?? []) as $conn) { $conn->send(json_encode(['topic' => $data['topic'], 'payload' => $data['payload']])); } } } public function onClose(ConnectionInterface $conn): void { // Clean up all subscriptions for this connection foreach ($this->subscriptions as $topic => & $conns) { $conns = array_filter($conns, fn($c) => $c !== $conn); } } public function onError(ConnectionInterface $conn, \Exception $e): void { echo "Error on {$conn->resourceId}: {$e->getMessage()}\n"; $conn->close(); // gracefully terminate the connection } } ``` -------------------------------- ### Ratchet\Server\IoServer Source: https://context7.com/ratchetphp/ratchet/llms.txt The foundational server that binds a TCP socket via ReactPHP and delegates I/O events to the application stack. It provides methods to run the server and manage its lifecycle. ```APIDOC ## `Ratchet\Server\IoServer` — Low-Level TCP Server The foundational server that binds a TCP socket via ReactPHP and delegates I/O events to the application stack. `IoServer::factory()` is a convenience constructor that creates the event loop and socket internally. ### Methods - **`factory(MessageComponentInterface $app, int $port, string $bindAddress)`**: A convenience constructor that creates the event loop and socket internally. - **`run()`**: Starts the server and begins processing events. ### Public Properties - **`loop`** (React\EventLoop\LoopInterface): The event loop instance. - **`app`** (MessageComponentInterface): The root application component. - **`socket`** (React\Socket\ServerInterface): The underlying socket server instance. ### Example Usage #### Option A: `IoServer::factory()` shortcut ```php run(); ``` #### Option B: Manual construction with a shared event loop ```php addPeriodicTimer(60, function () { echo "Server heartbeat — " . date('H:i:s') . "\n"; }); $server->run(); ``` ``` -------------------------------- ### Ratchet\Wamp\WampServerInterface Source: https://context7.com/ratchetphp/ratchet/llms.txt Implement this interface to handle WAMP events like subscriptions, publications, and RPC calls. The WampServer decorator manages Topic objects automatically. ```APIDOC ## `Ratchet\Wamp\WampServerInterface` — WAMP Pub/Sub & RPC Replaces `onMessage` with structured WAMP (WebSocket Application Messaging Protocol) events: topic subscriptions, publications, and RPC calls. Automatically managed via `WampServer` decorator, which provides `Topic` container objects. ### Methods - **`onSubscribe(ConnectionInterface $conn, $topic): void`**: Called when a client subscribes to a topic URI. - **`onUnSubscribe(ConnectionInterface $conn, $topic): void`**: Called when a client unsubscribes. - **`onPublish(ConnectionInterface $conn, $topic, $event, array $exclude, array $eligible): void`**: Called when a client publishes to a topic. Use `$topic->broadcast()` to send messages to subscribers. - **`onCall(ConnectionInterface $conn, $id, $topic, array $params): void`**: Called for Remote Procedure Calls. Respond using `$conn->callResult($id, ...)` or `$conn->callError($id, ...)`. - **`onOpen(ConnectionInterface $conn): void`**: Called when a new connection is opened. - **`onClose(ConnectionInterface $conn): void`**: Called when a connection is closed. - **`onError(ConnectionInterface $conn, Exception $e): void`**: Called when an error occurs on a connection. ``` -------------------------------- ### Ratchet\ConnectionInterface Source: https://context7.com/ratchetphp/ratchet/llms.txt Represents a single connected client. This object is passed into lifecycle callbacks and can have dynamic properties added to it. ```APIDOC ## `Ratchet\ConnectionInterface` — Connection Object The proxy object passed into every lifecycle callback, representing a single connected client. Ratchet decorates it with dynamic properties as it passes through the stack (e.g., `$conn->httpRequest`, `$conn->Session`, `$conn->WAMP`). ### Properties - **`resourceId`** (int): A unique integer ID derived from the stream resource. - **`remoteAddress`** (string): The client's IP address (e.g., "192.168.1.42"). - **`httpRequest`** (Psr\Http\Message\ServerRequestInterface): Available after the WsServer/HttpServer layer, provides details about the incoming HTTP request. ### Example Usage ```php clients = new \SplObjectStorage; } public function onOpen(ConnectionInterface $conn): void { $this->clients->attach($conn); // Built-in properties $id = $conn->resourceId; // (int) unique ID derived from stream resource $ip = $conn->remoteAddress; // (string) client IP, e.g. "192.168.1.42" // PSR-7 request available after WsServer/HttpServer layer $path = $conn->httpRequest->getUri()->getPath(); // e.g. "/chat" $qs = $conn->httpRequest->getUri()->getQuery(); // e.g. "room=general" parse_str($qs, $params); $conn->room = $params['room'] ?? 'default'; // store arbitrary data on the connection $conn->send(json_encode(['event' => 'welcome', 'room' => $conn->room])); } public function onMessage(ConnectionInterface $from, $msg): void { foreach ($this->clients as $client) { if ($client->room === $from->room && $client !== $from) { $client->send($msg); } } } public function onClose(ConnectionInterface $conn): void { $this->clients->detach($conn); } public function onError(ConnectionInterface $conn, \Exception $e): void { $conn->close(); } } ``` ``` -------------------------------- ### Protect WebSocket Connections with OriginCheck Source: https://context7.com/ratchetphp/ratchet/llms.txt A middleware decorator that rejects connections with non-matching HTTP Origin headers. Protects against CSRF-style attacks. Applied automatically by App::route() when allowedOrigins is not ['*']. ```php allowedOrigins[] = 'partner.example.com'; $routes = new RouteCollection; $routes->add('chat', new Route('/chat', ['_controller' => $originGuard], [], [], 'myapp.com', [], ['GET'])); $server = IoServer::factory( new HttpServer(new Router(new UrlMatcher($routes, new RequestContext))), 8080 ); $server->run(); // Connections from origins NOT in the list receive HTTP 403 Forbidden ``` -------------------------------- ### Route HTTP/WebSocket Requests with Router Source: https://context7.com/ratchetphp/ratchet/llms.txt Routes incoming requests to different application controllers based on URL path. Each controller must implement HttpServerInterface. Used automatically by App::route(). ```php add('chat', new Route( '/chat', ['_controller' => new WsServer(new ChatServer)], [], // requirements [], // options 'localhost', [], // schemes ['GET'] )); // Route: /game/{roomId} — parameterized WebSocket room // $conn->httpRequest->getUri()->getQuery() will contain roomId after Router merges it $routes->add('game', new Route( '/game/{roomId}', ['_controller' => new WsServer(new GameServer)], ['roomId' => '\d+'], [], 'localhost', [], ['GET'] )); $matcher = new UrlMatcher($routes, new RequestContext); $router = new Router($matcher); $server = IoServer::factory(new HttpServer($router), 8080); $server->run(); ``` -------------------------------- ### Share Symfony Sessions with Ratchet\Session\SessionProvider Source: https://context7.com/ratchetphp/ratchet/llms.txt Integrate Symfony HttpFoundation sessions into WebSocket connections by using SessionProvider. This allows WebSocket handlers to access authenticated user data written by a traditional web framework. ```php Session is populated by SessionProvider $conn->Session->start(); $userId = $conn->Session->get('user_id'); if (!$userId) { $conn->send(json_encode(['error' => 'Unauthenticated'])); $conn->close(); return; } echo "Authenticated user {$userId} connected\n"; } public function onMessage(\Ratchet\ConnectionInterface $from, $msg): void { $username = $from->Session->get('username', 'Guest'); // ... broadcast with username } public function onClose(\Ratchet\ConnectionInterface $conn): void {} public function onError(\Ratchet\ConnectionInterface $conn, \Exception $e): void { $conn->close(); } } // SessionProvider wraps WsServer (must be an HttpServerInterface layer) $server = IoServer::factory( new HttpServer( new SessionProvider( new WsServer(new AuthenticatedChat), $sessionHandler // optional: ['gc_maxlifetime' => 3600] session.ini overrides as 3rd arg ) ), 8080 ); $server->run(); ``` -------------------------------- ### Ratchet\Wamp\Topic Source: https://context7.com/ratchetphp/ratchet/llms.txt The Topic class manages subscribers for a named topic and supports targeted broadcasts. It is automatically provided by the TopicManager when using WampServer. ```APIDOC ## `Ratchet\Wamp\Topic` — Pub/Sub Topic Container Manages the set of `WampConnection` subscribers for a named topic. Provided automatically by `TopicManager` when using `WampServer`. Supports targeted broadcasts with session-ID–based exclude and eligible lists. ### Methods - **`getId(): string`**: Returns the unique identifier of the topic. - **`count(): int`**: Returns the number of subscribers to the topic (implements `Countable`). - **`broadcast(mixed $event, array $exclude = [], array $eligible = []): void`**: Broadcasts an event to subscribers, with options to exclude specific session IDs or target only specific session IDs. - **`has(ConnectionInterface $conn): bool`**: Checks if a specific connection is subscribed to the topic. - **`add(ConnectionInterface $conn): void`**: Adds a connection to the topic's subscriber list (typically managed by TopicManager). - **`remove(ConnectionInterface $conn): void`**: Removes a connection from the topic's subscriber list (typically managed by TopicManager). ``` -------------------------------- ### Ratchet\Http\Router Source: https://context7.com/ratchetphp/ratchet/llms.txt Routes incoming HTTP/WebSocket upgrade requests to different application controllers based on URL path. Powered by Symfony Routing; each controller must implement HttpServerInterface. Used automatically by App::route(). ```APIDOC ## `Ratchet\Http\Router` — URL-Based Routing Routes incoming HTTP/WebSocket upgrade requests to different application controllers based on URL path. Powered by Symfony Routing; each controller must implement `HttpServerInterface`. Used automatically by `App::route()`. ### Example Usage ```php add('chat', new Route( '/chat', ['_controller' => new WsServer(new ChatServer)], [], // requirements [], // options 'localhost', [], // schemes ['GET'] )); // Route: /game/{roomId} — parameterized WebSocket room // $conn->httpRequest->getUri()->getQuery() will contain roomId after Router merges it $routes->add('game', new Route( '/game/{roomId}', ['_controller' => new WsServer(new GameServer)], ['roomId' => '\d+'], [], 'localhost', [], ['GET'] )); $matcher = new UrlMatcher($routes, new RequestContext); $router = new Router($matcher); $server = IoServer::factory(new HttpServer($router), 8080); $server->run(); ?> ``` ``` -------------------------------- ### Ratchet\Http\OriginCheck Source: https://context7.com/ratchetphp/ratchet/llms.txt A middleware decorator that rejects WebSocket connections whose HTTP Origin header does not match an allowlist. Protects against CSRF-style attacks from third-party websites. Applied automatically by App::route() when allowedOrigins is not ['*']. ```APIDOC ## `Ratchet\Http\OriginCheck` — Cross-Origin Protection A middleware decorator that rejects WebSocket connections whose HTTP `Origin` header does not match an allowlist. Protects against CSRF-style attacks from third-party websites. Applied automatically by `App::route()` when `allowedOrigins` is not `['*']`. ### Example Usage ```php allowedOrigins[] = 'partner.example.com'; $routes = new RouteCollection; $routes->add('chat', new Route('/chat', ['_controller' => $originGuard], [], [], 'myapp.com', [], ['GET'])); $server = IoServer::factory( new HttpServer(new Router(new UrlMatcher($routes, new RequestContext))), 8080 ); $server->run(); // Connections from origins NOT in the list receive HTTP 403 Forbidden ?> ``` ``` -------------------------------- ### Ratchet\MessageComponentInterface Source: https://context7.com/ratchetphp/ratchet/llms.txt The primary interface every Ratchet application must implement. It combines onOpen, onClose, onError, and onMessage into a single contract for handling WebSocket messages. ```APIDOC ## `Ratchet\MessageComponentInterface` — Core Application Interface The primary interface every Ratchet application must implement. Combines `ComponentInterface` (onOpen, onClose, onError) and `MessageInterface` (onMessage) into a single contract. Used when message payloads are received as raw strings from the WebSocket layer. ### Methods - **`onOpen(ConnectionInterface $conn)`**: Called when a new connection is established. - **`onMessage(ConnectionInterface $from, $msg)`**: Called when a message is received from a client. - **`onClose(ConnectionInterface $conn)`**: Called when a connection is closed. - **`onError(ConnectionInterface $conn, Exception $e)`**: Called when an error occurs on a connection. ### Example Usage ```php [conn, ...] public function onOpen(ConnectionInterface $conn): void { // $conn->resourceId — unique integer ID for this connection // $conn->remoteAddress — client IP address echo "Client {$conn->resourceId} connected from {$conn->remoteAddress}\n"; } public function onMessage(ConnectionInterface $from, $msg): void { $data = json_decode($msg, true); if ($data['action'] === 'subscribe') { $this->subscriptions[$data['topic']][] = $from; $from->send(json_encode(['status' => 'subscribed', 'topic' => $data['topic']])); } elseif ($data['action'] === 'publish') { foreach (($this->subscriptions[$data['topic']] ?? []) as $conn) { $conn->send(json_encode(['topic' => $data['topic'], 'payload' => $data['payload']])); } } } public function onClose(ConnectionInterface $conn): void { // Clean up all subscriptions for this connection foreach ($this->subscriptions as $topic => & $conns) { $conns = array_filter($conns, fn($c) => $c !== $conn); } } public function onError(ConnectionInterface $conn, \Exception $e): void { echo "Error on {$conn->resourceId}: {$e->getMessage()}\n"; $conn->close(); // gracefully terminate the connection } } ``` ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.