### Basic Sockeon Server with WebSocket and HTTP Routes Source: https://github.com/sockeon/docs/blob/v2.0/index.md This example demonstrates a basic Sockeon server setup. It includes a controller that handles WebSocket connections and messages, as well as an HTTP route for API requests. Ensure you have the necessary PHP extensions installed. ```php emit($clientId, 'welcome', ['message' => 'Hello!']); } #[SocketOn('chat.message')] public function handleChatMessage(string $clientId, array $data): void { $this->broadcast('chat.message', [ 'user' => $clientId, 'message' => $data['message'] ]); } #[HttpRoute('GET', '/api/users')] public function getUsers(Request $request): Response { return Response::json(['users' => ['John', 'Jane']]); } } $config = new ServerConfig([ 'host' => '0.0.0.0', 'port' => 6001 ]); $server = new Server($config); $server->registerController(new MyController()); $server->run(); ``` -------------------------------- ### Basic Server Setup Source: https://github.com/sockeon/docs/blob/v2.0/api/server.md Sets up and starts a Sockeon server with custom configuration, middleware, and controllers. ```php '0.0.0.0', 'port' => 6001, 'debug' => true ]); // Create server $server = new Server($config); // Add middleware $server->addHttpMiddleware(CorsMiddleware::class); $server->addWebSocketMiddleware(AuthMiddleware::class); // Register controllers $server->registerController(new ChatController()); $server->registerController(new ApiController()); // Start server $host = $config->getHost(); $port = $config->getPort(); echo "Starting server on {$host}:{$port}\n"; $server->run(); ``` -------------------------------- ### Start Hybrid Server Source: https://github.com/sockeon/docs/blob/v2.0/examples/hybrid-server.md This snippet shows how to start the hybrid server. It includes example API endpoints and WebSocket events that the server will handle. Press Ctrl+C to stop the server. ```bash echo " GET /api/clients\n"; echo " POST /api/message/{clientId}\n"; echo "\nWebSocket events:\n"; echo " chat.message\n"; echo " notification.send\n"; echo "\nPress Ctrl+C to stop\n"; ``` ```php // Start server $server->run(); ``` -------------------------------- ### Install Sockeon with Composer Source: https://github.com/sockeon/docs/blob/v2.0/getting-started/installation.md Use Composer to install the Sockeon framework. This is the recommended installation method. ```bash composer require sockeon/sockeon ``` -------------------------------- ### Get Server Instance Example Source: https://github.com/sockeon/docs/blob/v2.0/api/controller.md Retrieves the server instance for direct access to server methods. This allows for advanced server introspection and control. ```php public function getServer(): Server ``` ```php #[HttpRoute('GET', '/api/status')] public function getStatus(Request $request): Response { $server = $this->getServer(); return Response::json([ 'clients_connected' => $server->getClientCount(), 'client_types' => $server->getClientTypes(), 'rate_limiting_enabled' => $server->isRateLimitingEnabled() ]); } ``` ```php #[SocketOn('server.info')] public function getServerInfo(string $clientId, array $data): void { $server = $this->getServer(); $this->emit($clientId, 'server.info', [ 'total_clients' => $server->getClientCount(), 'your_id' => $clientId, 'your_type' => $server->getClientType($clientId) ]); } ``` -------------------------------- ### Complete Reverse Proxy Configuration Example Source: https://github.com/sockeon/docs/blob/v2.0/core/server-configuration.md Example of `ServerConfig` setup for reverse proxy scenarios, including trust proxy ranges and health check path. ```php use Sockeon\Sockeon\Config\ServerConfig; $config = new ServerConfig([ 'host' => '0.0.0.0', 'port' => 6001, 'trust_proxy' => [ '127.0.0.1', '10.0.0.0/8', '172.16.0.0/12', '192.168.0.0/16', ], 'health_check_path' => '/health', ]); ``` -------------------------------- ### Complete PHP WebSocket Client Example Source: https://github.com/sockeon/docs/blob/v2.0/websocket/client.md A full example combining client creation, event handling, connection, message sending, and running the client loop. ```php on('welcome', function($data) { echo "Welcome: {" . $data['message'] . "}\n"; }); $client->on('chat.message', function($data) { echo "Chat: {" . $data['message'] . "}\n"; }); $client->on('error', function($data) { echo "Error: {" . $data['message'] . "}\n"; }); // Connect to server try { $client->connect(); echo "Connected to server\n"; // Send a message $client->emit('chat.message', [ 'message' => 'Hello from PHP client!' ]); // Keep connection alive $client->run(); } catch (Exception $e) { echo "Failed to connect: " . $e->getMessage() . "\n"; } ``` -------------------------------- ### Create Sockeon Server Source: https://github.com/sockeon/docs/blob/v2.0/getting-started/quick-start.md This PHP script sets up and configures a Sockeon server, registers a controller, and starts the server. Ensure you have the Sockeon library installed via Composer. ```php '0.0.0.0', 'port' => 6001, 'debug' => true, 'cors' => [ 'allowed_origins' => ['*'], 'allowed_methods' => ['GET', 'POST', 'PUT', 'DELETE', 'OPTIONS'], 'allowed_headers' => ['Content-Type', 'Authorization'] ] ]); // Create and configure the server $server = new Server($config); // Register the chat controller $server->registerController(new ChatController()); $host = $config->getHost(); $port = $config->getPort(); echo "Starting Sockeon server on {$host}:{$port}\n"; echo "WebSocket endpoint: ws://{$host}:{$port}\n"; echo "HTTP API: http://{$host}:{$port}/api\n"; // Start the server $server->run(); ``` -------------------------------- ### Game Controller Example Source: https://github.com/sockeon/docs/blob/v2.0/getting-started/basic-concepts.md A practical example of a Sockeon controller managing client connections, joining namespaces and rooms, and broadcasting game events. ```php class GameController extends SocketController { #[OnConnect] public function onConnect(string $clientId): void { // All game clients start in the lobby $this->joinNamespace($clientId, '/game'); $this->joinRoom($clientId, 'lobby', '/game'); } #[SocketOn('game.join')] public function joinGame(string $clientId, array $data): void { $gameId = $data['gameId']; // Move from lobby to specific game room $this->leaveRoom($clientId, 'lobby', '/game'); $this->joinRoom($clientId, "game_{$gameId}", '/game'); // Notify other players in the game $this->broadcastToRoomClients('player.joined', [ 'playerId' => $clientId ], "game_{$gameId}", '/game'); } } ``` -------------------------------- ### Focused Middleware Example (PHP) Source: https://github.com/sockeon/docs/blob/v2.0/core/middleware.md Illustrates the principle of keeping middleware focused on a single responsibility, showing examples of good and bad practices. ```php // Good - focused on authentication class AuthMiddleware implements HttpMiddleware { ... } // Good - focused on validation class ValidationMiddleware implements HttpMiddleware { ... } // Bad - too many responsibilities class EverythingMiddleware implements HttpMiddleware { ... } ``` -------------------------------- ### Get Server Start Time Source: https://github.com/sockeon/docs/blob/v2.0/api/server.md Retrieves the server's start time as a Unix timestamp with microseconds. Returns null if the server has not started. ```php public function getStartTime(): ?float ``` ```php $startTime = $server->getStartTime(); if ($startTime !== null) { echo "Server started at: " . date('Y-m-d H:i:s', (int)$startTime) . "\n"; } ``` -------------------------------- ### Install Sockeon with Composer Source: https://github.com/sockeon/docs/blob/v2.0/getting-started/quick-start.md Defines project dependencies and autoloading configuration for a Sockeon application. Run `composer install` to install dependencies. ```json { "require": { "sockeon/sockeon": "^2.0" }, "autoload": { "psr-4": { "App\": "src/" } } } ``` ```bash composer install ``` -------------------------------- ### Example: Get Response Headers Source: https://github.com/sockeon/docs/blob/v2.0/api/response.md This snippet demonstrates retrieving all headers from a response, including default ones like 'Content-Type' and custom ones. ```php #[HttpRoute('GET', '/api/debug')] public function debugResponse(Request $request): Response { $response = Response::json(['debug' => true], 200, [ 'X-Debug' => 'enabled', 'X-Request-ID' => uniqid() ]); $headers = $response->getHeaders(); /* Returns: [ 'Content-Type' => 'application/json', 'X-Debug' => 'enabled', 'X-Request-ID' => '...' ] */ return $response; } ``` -------------------------------- ### Chat Controller Example Source: https://github.com/sockeon/docs/blob/v2.0/getting-started/basic-concepts.md A complete example of a chat controller demonstrating connection, message handling, and disconnection events. ```php class ChatController extends SocketController { #[OnConnect] public function welcome(string $clientId): void { $this->emit($clientId, 'welcome', ['message' => 'Hello!']); } #[SocketOn('chat.message')] public function handleMessage(string $clientId, array $data): void { $this->broadcast('chat.message', $data); } #[OnDisconnect] public function goodbye(string $clientId): void { $this->broadcast('user.left', ['user' => $clientId]); } } ``` -------------------------------- ### run() Source: https://github.com/sockeon/docs/blob/v2.0/api/server.md Starts the server and begins listening for connections. This method blocks until the server is stopped. ```APIDOC ## run() ### Description Starts the server and begins listening for connections. This method blocks until the server is stopped. ### Method `public function run(): void` ### Example ```php $server->run(); // Server starts and blocks here ``` ``` -------------------------------- ### Room Naming Examples Source: https://github.com/sockeon/docs/blob/v2.0/core/namespaces-rooms.md Provides examples of good and bad room naming conventions. Descriptive and consistent names are crucial for managing specific communication channels. ```php // Good - descriptive and consistent 'general' // General chat room 'room_123' // Specific room with ID 'game_456' // Game session 'private_1_2' // Private room between users 1 and 2 // Bad - unclear or inconsistent 'r123' // Unclear abbreviation 'TheAwesomeRoom' // Inconsistent casing ``` -------------------------------- ### Include Sockeon Autoloader (Manual Install) Source: https://github.com/sockeon/docs/blob/v2.0/getting-started/installation.md If installing manually, include the Composer autoloader file to access Sockeon classes. ```php '127.0.0.1', 'port' => 6001, 'debug' => true ]); // Create the server instance $server = new Server($config); $host = $config->getHost(); $port = $config->getPort(); echo "Sockeon server created successfully!\n"; echo "Server configured for {$host}:{$port}\n"; ``` -------------------------------- ### JSON Server Configuration Example Source: https://github.com/sockeon/docs/blob/v2.0/core/server-configuration.md An example of a Sockeon server configuration file in JSON format, detailing various settings including host, port, debug mode, CORS, and rate limiting. ```json { "host": "0.0.0.0", "port": 6001, "debug": false, "trust_proxy": [ "127.0.0.1", "10.0.0.0/8", "192.168.0.0/16" ], "health_check_path": "/health", "cors": { "allowed_origins": ["https://example.com"], "allowed_methods": ["GET", "POST"], "allowed_headers": ["Content-Type"] }, "rate_limit": { "enabled": true, "maxHttpRequestsPerIp": 100, "httpTimeWindow": 60 } } ``` -------------------------------- ### Install Development Dependencies Source: https://github.com/sockeon/docs/blob/v2.0/getting-started/installation.md Install additional dependencies required for development and testing, including PestPHP and PHPStan. ```bash composer install --dev ``` -------------------------------- ### INI Server Configuration Example Source: https://github.com/sockeon/docs/blob/v2.0/core/server-configuration.md An example of a Sockeon server configuration file in INI format. Note that 'trust_proxy' cannot be set directly in INI and requires using setters or array configuration. ```ini ; sockeon.ini host = 0.0.0.0 port = 6001 debug = false auth_key = your-secret-key health_check_path = /health ; Note: trust_proxy cannot be set in INI format, use setters or array config ``` -------------------------------- ### Run Sockeon Server Source: https://github.com/sockeon/docs/blob/v2.0/getting-started/quick-start.md Execute this command in your terminal to start the Sockeon server. Ensure you are in the directory containing `server.php`. ```bash php server.php ``` -------------------------------- ### Example: Log Response Body Source: https://github.com/sockeon/docs/blob/v2.0/api/response.md This snippet demonstrates retrieving the response body and logging it for debugging purposes. ```php #[HttpRoute('GET', '/api/preview')] public function previewContent(Request $request): Response { $response = Response::ok('

Preview

')->setContentType('text/html'); $body = $response->getBody(); // '

Preview

' // Log the response body error_log("Response body: " . $body); return $response; } ``` -------------------------------- ### Run HTTP Server Source: https://github.com/sockeon/docs/blob/v2.0/examples/http-server.md Command to execute the PHP server script. Ensure you have PHP and Composer installed. ```bash php http-server.php ``` -------------------------------- ### Game Controller Example Source: https://github.com/sockeon/docs/blob/v2.0/core/controllers.md Demonstrates managing clients within rooms and namespaces for a game scenario, including connection, creation, joining, and leaving games. ```php class GameController extends SocketController { #[OnConnect] public function onConnect(string $clientId): void { // Add to game namespace and lobby $this->moveClientToNamespace($clientId, '/game'); $this->joinRoom($clientId, 'lobby', '/game'); $this->emit($clientId, 'game.status', [ 'location' => 'lobby', 'namespace' => '/game' ]); } #[SocketOn('game.create')] public function createGame(string $clientId, array $data): void { $gameId = uniqid('game_'); // Move creator from lobby to new game room $this->leaveRoom($clientId, 'lobby', '/game'); $this->joinRoom($clientId, $gameId, '/game'); $this->emit($clientId, 'game.created', [ 'gameId' => $gameId, 'role' => 'host' ]); // Notify lobby about new game $this->broadcastToRoomClients('game.available', [ 'gameId' => $gameId, 'host' => $clientId ], 'lobby', '/game'); } #[SocketOn('game.join')] public function joinGame(string $clientId, array $data): void { $gameId = $data['gameId'] ?? null; if (!$gameId) { $this->emit($clientId, 'error', ['message' => 'Game ID required']); return; } // Move from lobby to game $this->leaveRoom($clientId, 'lobby', '/game'); $this->joinRoom($clientId, $gameId, '/game'); // Notify game participants $this->broadcastToRoomClients('player.joined', [ 'playerId' => $clientId ], $gameId, '/game'); $this->emit($clientId, 'game.joined', [ 'gameId' => $gameId, 'role' => 'player' ]); } #[SocketOn('game.leave')] public function leaveGame(string $clientId, array $data): void { $gameId = $data['gameId'] ?? null; if ($gameId) { // Leave game room and return to lobby $this->leaveRoom($clientId, $gameId, '/game'); $this->joinRoom($clientId, 'lobby', '/game'); // Notify remaining players $this->broadcastToRoomClients('player.left', [ 'playerId' => $clientId ], $gameId, '/game'); } } #[OnDisconnect] public function onDisconnect(string $clientId): void { // Cleanup is automatic when client disconnects // But you might want to notify other players $this->broadcast('player.disconnected', [ 'playerId' => $clientId ], '/game'); } } ``` -------------------------------- ### HTTP GET Request Handler Source: https://github.com/sockeon/docs/blob/v2.0/getting-started/basic-concepts.md An example of a controller method handling an HTTP GET request with a path parameter and returning a JSON response. ```php #[HttpRoute('GET', '/api/users/{id}')] public function getUser(Request $request): Response { $id = $request->getParam('id'); $user = $this->findUser($id); return Response::json($user); } ``` -------------------------------- ### Example: Get Status Code Source: https://github.com/sockeon/docs/blob/v2.0/api/response.md This snippet demonstrates retrieving the status code of a JSON response. ```php #[HttpRoute('GET', '/api/status-check')] public function statusCheck(Request $request): Response { $response = Response::json(['status' => 'ok']); $statusCode = $response->getStatusCode(); // 200 return $response; } ``` -------------------------------- ### Initialize Sockeon Server Source: https://github.com/sockeon/docs/blob/v2.0/getting-started/basic-concepts.md This snippet shows how to create a new Sockeon server instance using the provided configuration. ```php use Sockeon\Sockeon\Config\ServerConfig; use Sockeon\Sockeon\Connection\Server; $config = new ServerConfig(); $server = new Server($config); ``` -------------------------------- ### Register Controllers and Run Server Source: https://github.com/sockeon/docs/blob/v2.0/api/router.md This snippet shows the typical way to instantiate the Sockeon Server, register controller instances, and start the server. It is the standard entry point for a Sockeon application. ```php $server = new Server($config); $server->registerController(new ChatController()); $server->registerController(new ApiController()); $server->run(); ``` -------------------------------- ### Get Server Uptime Source: https://github.com/sockeon/docs/blob/v2.0/api/server.md Retrieves the server's uptime in seconds. Returns null if the server has not started. ```php public function getUptime(): ?int ``` ```php $uptime = $server->getUptime(); if ($uptime !== null) { echo "Server has been running for {$uptime} seconds\n"; echo "That's " . round($uptime / 3600, 2) . " hours\n"; } ``` -------------------------------- ### Start the Server Source: https://github.com/sockeon/docs/blob/v2.0/api/server.md Initiate the Sockeon server to begin listening for incoming connections. This method is blocking and will run until the server is explicitly stopped. ```php $server->run(); // Server starts and blocks here ``` -------------------------------- ### Server Configuration via Constructor Source: https://github.com/sockeon/docs/blob/v2.0/core/server-configuration.md Initialize `ServerConfig` with an array of settings, including host, port, trust proxy, proxy headers, and health check path. ```php use Sockeon\Sockeon\Config\ServerConfig; $config = new ServerConfig([ 'host' => '0.0.0.0', 'port' => 6001, 'trust_proxy' => [ '127.0.0.1', '10.0.0.0/8', '192.168.0.0/16', ], 'proxy_headers' => [ 'proto' => 'X-Forwarded-Proto', 'host' => 'X-Forwarded-Host', 'port' => 'X-Forwarded-Port', ], 'health_check_path' => '/health', ]); ``` -------------------------------- ### Get Complete Server Information Source: https://github.com/sockeon/docs/blob/v2.0/api/server.md Fetches comprehensive server information, including client count, uptime, start time, and health check path. This is useful for monitoring and diagnostics. ```php #[HttpRoute('GET', '/api/server-info')] public function getServerInfo(Request $request): Response { $server = $this->getServer(); return Response::json([ 'clients' => $server->getClientCount(), 'uptime' => $server->getUptime(), 'uptime_human' => $server->getUptimeString(), 'start_time' => $server->getStartTime(), 'health_check' => $server->getHealthCheckPath(), ]); } ``` -------------------------------- ### Initialize ServerConfig with Setters Source: https://github.com/sockeon/docs/blob/v2.0/core/server-configuration.md Configure ServerConfig by creating an instance and using setter methods for host, port, and debug mode. ```php use Sockeon\Sockeon\Config\ServerConfig; $config = new ServerConfig(); $config->setHost('0.0.0.0'); $config->setPort(6001); $config->setDebug(false); ``` -------------------------------- ### Define HTTP Routes with `#[HttpRoute]` Source: https://github.com/sockeon/docs/blob/v2.0/core/controllers.md Use the `#[HttpRoute]` attribute to define GET, POST, and other HTTP methods for controller actions. This example shows how to handle status, client, and broadcast endpoints. ```php use Sockeon\Sockeon\Http\Attributes\HttpRoute; use Sockeon\Sockeon\Http\Request; use Sockeon\Sockeon\Http\Response; class ApiController extends SocketController { #[HttpRoute('GET', '/api/status')] public function getStatus(Request $request): Response { return Response::json([ 'status' => 'online', 'clients' => $this->getClientCount(), 'uptime' => time() - $_SERVER['REQUEST_TIME'], 'timestamp' => time() ]); } #[HttpRoute('GET', '/api/clients')] public function getClients(Request $request): Response { $clients = []; foreach (array_keys($this->getAllClients()) as $clientId) { $clients[] = [ 'id' => $clientId, 'type' => $this->getClientType($clientId), 'connected_at' => time() // You'd track this in your app ]; } return Response::json([ 'count' => count($clients), 'clients' => $clients ]); } #[HttpRoute('POST', '/api/broadcast')] public function broadcastMessage(Request $request): Response { $data = $request->all(); if (!isset($data['event']) || !isset($data['data'])) { return Response::json([ 'error' => 'Missing required fields: event, data' ], 400); } $this->broadcast($data['event'], $data['data']); return Response::json(['success' => true]); } } ``` -------------------------------- ### Apply Conservative Rate Limit Source: https://github.com/sockeon/docs/blob/v2.0/advanced/rate-limiting.md Start with strict limits for sensitive operations and adjust based on observed usage. This example sets a very conservative limit of 5 requests per 60 seconds. ```php // Start with strict limits, then adjust based on usage #[RateLimit(maxCount: 5, timeWindow: 60)] // Very conservative public function sensitiveOperation(Request $request): Response { // Implementation } ``` -------------------------------- ### Sockeon PHP Client Usage Example Source: https://github.com/sockeon/docs/blob/v2.0/api/client.md Demonstrates how to instantiate the Sockeon client, configure auto-reconnect, register event listeners for 'welcome' and 'chat.message', connect to the server, emit chat events, and run the client loop. ```php use Sockeon\Sockeon\Connection\Client; use RuntimeException; $client = (new Client('localhost', 6001)) ->setAutoReconnect(true, 5, 3) ->on('welcome', function (array $data): void { echo "Server says: " . ($data['message'] ?? 'hello') . PHP_EOL; }) ->on('chat.message', function (array $data): void { echo '[' . ($data['from'] ?? 'unknown') . '] ' . ($data['message'] ?? '') . PHP_EOL; }); if (!$client->connect()) { throw new RuntimeException('Connection failed'); } $client->emit('chat.join', ['room' => 'general']); $client->emit('chat.message', ['message' => 'Hello from PHP client']); $client->run(); ``` -------------------------------- ### Basic WebSocket Client Usage in PHP Source: https://github.com/sockeon/docs/blob/v2.0/websocket/client.md Demonstrates the fundamental steps to create, connect, send, listen, and disconnect a WebSocket client. ```php use Sockeon\Sockeon\Connection\Client; // Create and connect to WebSocket server $client = new Client('localhost', 8080); // Connect to server $client->connect(); // Send a message $client->emit('hello', ['message' => 'Hello from PHP client!']); // Listen for messages $client->on('message', function($data) { echo "Received: " . json_encode($data) . "\n"; }); // Keep connection alive $client->run(); // Close connection $client->disconnect(); ``` -------------------------------- ### Project Structure Source: https://github.com/sockeon/docs/blob/v2.0/getting-started/quick-start.md The recommended directory structure for a Sockeon application. ```bash my-sockeon-app/ ├── composer.json ├── server.php └── src/ └── Controllers/ └── ChatController.php ``` -------------------------------- ### Configure WebSocket Client Connection Options Source: https://github.com/sockeon/docs/blob/v2.0/websocket/client.md Shows how to create a client and connect with custom headers for authentication or other purposes. ```php use Sockeon\Sockeon\Connection\Client; // Create client with host and port $client = new Client('localhost', 8080); // Connect with optional headers $client->connect([ 'Authorization' => 'Bearer your-token', 'User-Agent' => 'Sockeon-Client/1.0' ]); ``` -------------------------------- ### Loading Server Configuration from Environment Variables in PHP Source: https://github.com/sockeon/docs/blob/v2.0/core/server-configuration.md Shows how to configure Sockeon server settings using environment variables in PHP, with fallback defaults. It covers direct instantiation and using setter methods. ```php use Sockeon\Sockeon\Config\ServerConfig; $config = new ServerConfig([ 'host' => $_ENV['SOCKEON_HOST'] ?? '0.0.0.0', 'port' => (int)($_ENV['SOCKEON_PORT'] ?? 6001), 'debug' => filter_var($_ENV['SOCKEON_DEBUG'] ?? false, FILTER_VALIDATE_BOOLEAN), 'auth_key' => $_ENV['SOCKEON_AUTH_KEY'] ?? null, 'trust_proxy' => isset($_ENV['TRUSTED_PROXY_IPS']) ? explode(',', $_ENV['TRUSTED_PROXY_IPS']) : ['127.0.0.1'], 'health_check_path' => $_ENV['HEALTH_CHECK_PATH'] ?? null ]); // Or using setters $config = new ServerConfig(); $config->setHost($_ENV['SOCKEON_HOST'] ?? '0.0.0.0'); $config->setPort((int)($_ENV['SOCKEON_PORT'] ?? 6001)); $config->setDebug(filter_var($_ENV['SOCKEON_DEBUG'] ?? false, FILTER_VALIDATE_BOOLEAN)); $config->setAuthKey($_ENV['SOCKEON_AUTH_KEY'] ?? null); if (isset($_ENV['TRUSTED_PROXY_IPS'])) { $config->setTrustProxy(explode(',', $_ENV['TRUSTED_PROXY_IPS'])); } if (isset($_ENV['HEALTH_CHECK_PATH'])) { $config->setHealthCheckPath($_ENV['HEALTH_CHECK_PATH']); } ``` -------------------------------- ### Get User by ID Route Source: https://github.com/sockeon/docs/blob/v2.0/http/routing.md Defines a GET route to retrieve a user by their ID, extracting the ID from the route parameters. ```php class ApiController extends SocketController { #[HttpRoute('GET', '/api/users/{id}')] public function getUser(Request $request): Response { $userId = $request->getParam('id'); // Get user logic here $user = ['id' => $userId, 'name' => 'John Doe', 'email' => 'john@example.com']; return Response::json($user); } // ... other methods } ``` -------------------------------- ### Controller Organization Examples Source: https://github.com/sockeon/docs/blob/v2.0/core/controllers.md Illustrates the principle of single responsibility for controllers and demonstrates various methods for registering multiple controllers with a server instance. ```php // Good: Focused on chat functionality class ChatController extends SocketController { ... } // Good: Focused on game functionality class GameController extends SocketController { ... } // Good: Focused on user management class UserController extends SocketController { ... } // Bad: Too many responsibilities class EverythingController extends SocketController { ... } ``` ```php $server = new Server($config); // Register different controllers for different features $server->registerController(new ChatController()); $server->registerController(new GameController()); $server->registerController(new UserController()); $server->registerController(new NotificationController()); $server->registerController(new ApiController()); $server->run(); ``` ```php $server = new Server($config); // Register multiple controllers at once $server->registerControllers([ new ChatController(), new GameController(), new UserController(), new NotificationController(), new ApiController() ]); $server->run(); ``` ```php $server = new Server($config); // Register controllers by class name (they will be instantiated automatically) $server->registerControllers([ ChatController::class, GameController::class, UserController::class, NotificationController::class, ApiController::class ]); $server->run(); ``` ```php $server = new Server($config); // Mix instantiated controllers and class names $server->registerControllers([ new ChatController(), GameController::class, // Will be instantiated automatically new UserController(), NotificationController::class, new ApiController() ]); $server->run(); ``` -------------------------------- ### Test Get Users Endpoint Source: https://github.com/sockeon/docs/blob/v2.0/examples/http-server.md Use curl to send GET requests to the /api/users endpoint, with optional pagination parameters. ```bash curl http://localhost:8080/api/users curl http://localhost:8080/api/users?page=1&limit=5 ``` -------------------------------- ### Get User Endpoint Source: https://github.com/sockeon/docs/blob/v2.0/http/routing.md Defines a GET endpoint to retrieve a specific user by their ID. The user ID is passed as a path parameter. ```APIDOC ## GET /api/users/{id} ### Description Retrieves a specific user by their ID. ### Method GET ### Endpoint /api/users/{id} ### Parameters #### Path Parameters - **id** (string) - Required - The ID of the user to retrieve. ### Response #### Success Response (200) - **id** (string) - The ID of the user. - **name** (string) - The name of the user. - **email** (string) - The email of the user. ### Response Example { "id": "123", "name": "John Doe", "email": "john.doe@example.com" } ``` -------------------------------- ### Middleware Order Example (PHP) Source: https://github.com/sockeon/docs/blob/v2.0/core/middleware.md Demonstrates the correct logical order for applying multiple HTTP middleware to ensure proper request processing, such as CORS, authentication, and validation. ```php // Correct order $server->addHttpMiddleware(CorsMiddleware::class); // Handle CORS first $server->addHttpMiddleware(AuthMiddleware::class); // Auth before validation $server->addHttpMiddleware(ValidationMiddleware::class); // Validate last // Note: Rate limiting is handled automatically via #[RateLimit] attribute ``` -------------------------------- ### Loading Server Configuration from INI File in PHP Source: https://github.com/sockeon/docs/blob/v2.0/core/server-configuration.md Demonstrates loading Sockeon server configuration from an INI file in PHP. It shows how to parse the INI file and apply settings using direct instantiation or setters. 'trust_proxy' requires separate handling. ```php use Sockeon\Sockeon\Config\ServerConfig; $configData = parse_ini_file('sockeon.ini'); $config = new ServerConfig([ 'host' => $configData['host'], 'port' => (int)$configData['port'], 'debug' => filter_var($configData['debug'], FILTER_VALIDATE_BOOLEAN), 'auth_key' => $configData['auth_key'] ?? null, 'health_check_path' => $configData['health_check_path'] ?? null ]); // Trust proxy must be set separately if needed if (isset($configData['trusted_proxy_ips'])) { $config->setTrustProxy(explode(',', $configData['trusted_proxy_ips'])); } // Or using setters $config = new ServerConfig(); $config->setHost($configData['host']); $config->setPort((int)$configData['port']); $config->setDebug(filter_var($configData['debug'], FILTER_VALIDATE_BOOLEAN)); $config->setAuthKey($configData['auth_key'] ?? null); if (isset($configData['health_check_path'])) { $config->setHealthCheckPath($configData['health_check_path']); } if (isset($configData['trusted_proxy_ips'])) { $config->setTrustProxy(explode(',', $configData['trusted_proxy_ips'])); } ``` -------------------------------- ### Namespace Organization Examples Source: https://github.com/sockeon/docs/blob/v2.0/core/namespaces-rooms.md Illustrates good and bad practices for organizing namespaces. Use clear, feature-based names to avoid confusion and maintain structure. ```php // Good - clear separation by feature '/chat' // Chat functionality '/game' // Game functionality '/admin' // Admin panel '/api' // API connections // Bad - unclear or too nested '/app/chat/general' // Too nested '/stuff' // Unclear purpose ``` -------------------------------- ### Get Connected Clients via HTTP API Source: https://github.com/sockeon/docs/blob/v2.0/examples/hybrid-server.md Retrieve a list of currently connected WebSocket clients using an HTTP GET request. ```bash # Get connected clients curl http://localhost:8080/api/clients ``` -------------------------------- ### Get Server Status via HTTP API Source: https://github.com/sockeon/docs/blob/v2.0/examples/hybrid-server.md Retrieve the current status of the server and connected clients using an HTTP GET request. ```bash # Get server status curl http://localhost:8080/api/status ``` -------------------------------- ### Get All Query Parameters Source: https://github.com/sockeon/docs/blob/v2.0/api/request.md Retrieves all query string parameters from the URL as an associative array. Useful for handling GET requests with multiple filters or options. ```php public function getQueryParams(): array ``` ```php #[HttpRoute('GET', '/api/users')]\npublic function listUsers(Request $request): Response\n{\n $queryParams = $request->getQueryParams();\n /*\n For URL: /api/users?page=2&limit=10&sort=name\n Returns: ['page' => '2', 'limit' => '10', 'sort' => 'name']\n */\n \n $page = (int)($queryParams['page'] ?? 1);\n $limit = (int)($queryParams['limit'] ?? 20);\n $sort = $queryParams['sort'] ?? 'id';\n \n return Response::json([ 'page' => $page, 'limit' => $limit, 'sort' => $sort ]); } ``` -------------------------------- ### HTTP GET Endpoint for Listing Users Source: https://github.com/sockeon/docs/blob/v2.0/api/controller.md Defines an HTTP GET endpoint at '/api/users' to list users. It returns a JSON response containing a list of users. ```php #[HttpRoute('GET', '/api/users')] public function listUsers(Request $request): Response { return Response::json(['users' => []]); } ``` -------------------------------- ### Comprehensive Production Server Configuration Source: https://github.com/sockeon/docs/blob/v2.0/core/server-configuration.md Set up a Sockeon server for a production environment with detailed configurations for logging, security, CORS, and extensive rate limiting options. This example demonstrates setting a custom logger and various security-related parameters. ```php setMinLogLevel('warning'); // Only log warnings and errors in production $logger->setLogToFile(true); $logger->setLogDirectory('/var/log/sockeon'); $logger->setLogToConsole(false); // Disable console logging in production // Create server config with all settings $config = new ServerConfig([ 'host' => '0.0.0.0', 'port' => 6001, 'debug' => false, 'auth_key' => $_ENV['SOCKEON_AUTH_KEY'] ?? null, 'queue_file' => '/tmp/sockeon_queue.json', 'trust_proxy' => [ '127.0.0.1', '10.0.0.0/8', '172.16.0.0/12', '192.168.0.0/16', ], 'health_check_path' => '/health', 'cors' => [ 'allowed_origins' => [ 'https://yourdomain.com', 'https://www.yourdomain.com', 'https://admin.yourdomain.com' ], 'allowed_methods' => ['GET', 'POST', 'PUT', 'DELETE', 'OPTIONS'], 'allowed_headers' => [ 'Content-Type', 'Authorization', 'X-Requested-With', 'X-API-Key' ], 'allow_credentials' => true, 'max_age' => 3600 ], 'rate_limit' => [ 'enabled' => true, 'maxHttpRequestsPerIp' => 1000, 'httpTimeWindow' => 3600, // 1 hour 'maxWebSocketMessagesPerClient' => 500, 'webSocketTimeWindow' => 60, // 1 minute 'maxConnectionsPerIp' => 100, 'connectionTimeWindow' => 3600, // 1 hour 'maxGlobalConnections' => 50000, 'burstAllowance' => 50, 'cleanupInterval' => 1800, // 30 minutes 'whitelist' => [ '127.0.0.1', // Localhost '10.0.0.0/8', // Internal network '192.168.1.100' // Admin IP ] ] ]); // Set the custom logger $config->setLogger($logger); return $config; ``` -------------------------------- ### HTTP GET Endpoint for Specific User Source: https://github.com/sockeon/docs/blob/v2.0/api/controller.md Defines an HTTP GET endpoint at '/api/users/{id}' to retrieve a specific user by their ID. The user ID is extracted from the URL parameters. ```php #[HttpRoute('GET', '/api/users/{id}')] public function getUser(Request $request): Response { $userId = $request->getParam('id'); // Get user logic return Response::json(['user' => ['id' => $userId]]); } ``` -------------------------------- ### Login Rate Limiting Example Source: https://github.com/sockeon/docs/blob/v2.0/advanced/rate-limiting.md Implement rate limiting specifically for login attempts to prevent brute-force attacks. This example limits login attempts to 3 per 15 minutes. ```php #[HttpRoute('POST', '/api/login')] #[RateLimit(maxCount: 3, timeWindow: 900)] // 3 attempts per 15 minutes public function login(Request $request): Response { $data = $request->all(); if ($this->validateCredentials($data)) { return Response::json(['success' => true]); } return Response::json(['error' => 'Invalid credentials'], 401); } ``` -------------------------------- ### Initialize ServerConfig with Array Source: https://github.com/sockeon/docs/blob/v2.0/core/server-configuration.md Instantiate ServerConfig using an associative array for basic server settings like host, port, and debug mode. ```php use Sockeon\Sockeon\Config\ServerConfig; $config = new ServerConfig([ 'host' => '0.0.0.0', 'port' => 6001, 'debug' => false ]); ``` -------------------------------- ### Chat Message Rate Limiting Example Source: https://github.com/sockeon/docs/blob/v2.0/advanced/rate-limiting.md Apply rate limiting to chat messages to prevent spam. This example limits chat messages to 20 per minute and includes a check for empty messages. ```php #[SocketOn('chat.message')] #[RateLimit(maxCount: 20, timeWindow: 60)] // 20 messages per minute public function handleChatMessage(string $clientId, array $data): void { $message = trim($data['message'] ?? ''); if (empty($message)) { $this->emit($clientId, 'error', ['message' => 'Message cannot be empty']); return; } $this->broadcast('chat.message', [ 'user' => $clientId, 'message' => $message, 'timestamp' => time() ]); } ``` -------------------------------- ### Running Multiple Sockeon Server Instances Source: https://github.com/sockeon/docs/blob/v2.0/advanced/reverse-proxy.md Start multiple Sockeon server instances on different ports to prepare for load balancing. ```bash # Server 1 php server.php --port=6001 # Server 2 php server.php --port=6002 # Server 3 php server.php --port=6003 ``` -------------------------------- ### Multi-Tenant Chat Application Setup Source: https://github.com/sockeon/docs/blob/v2.0/core/namespaces-rooms.md Manages client connections and facilitates joining tenant-specific namespaces and rooms. Handles user identification and broadcasts connection events within a tenant's namespace. ```php class MultiTenantChatController extends SocketController { #[OnConnect] public function onConnect(string $clientId): void { // Clients start in default namespace $this->emit($clientId, 'connected', [ 'clientId' => $clientId, 'message' => 'Please select a tenant to join' ]); } #[SocketOn('tenant.join')] public function joinTenant(string $clientId, array $data): void { $tenantId = $data['tenantId'] ?? null; $userId = $data['userId'] ?? null; if (!$tenantId || !$userId) { $this->emit($clientId, 'error', ['message' => 'Tenant ID and User ID required']); return; } // Create tenant-specific namespace $namespace = "/tenant_{$tenantId}"; // Join tenant namespace $this->moveClientToNamespace($clientId, $namespace); // Join general room in tenant $this->joinRoom($clientId, 'general', $namespace); // Store user info $this->setClientData($clientId, 'userId', $userId); $this->setClientData($clientId, 'tenantId', $tenantId); // Notify tenant about new user $this->broadcastToNamespaceClients('user.joined', [ 'userId' => $userId, 'clientId' => $clientId, 'tenantId' => $tenantId ], $namespace); $this->emit($clientId, 'tenant.joined', [ 'tenantId' => $tenantId, 'namespace' => $namespace ]); } #[SocketOn('chat.message')] public function sendMessage(string $clientId, array $data): void { $userId = $this->getClientData($clientId, 'userId'); $tenantId = $this->getClientData($clientId, 'tenantId'); if (!$tenantId) { $this->emit($clientId, 'error', ['message' => 'Not connected to any tenant']); return; } $message = $data['message'] ?? ''; $room = $data['room'] ?? 'general'; $namespace = "/tenant_{$tenantId}"; // Broadcast to tenant room $this->broadcastToRoomClients('chat.message', [ 'userId' => $userId, 'message' => $message, 'room' => $room, 'timestamp' => time() ], $room, $namespace); } } ``` -------------------------------- ### Include Context in Log Messages in PHP Source: https://github.com/sockeon/docs/blob/v2.0/advanced/logging.md This snippet emphasizes the importance of including relevant context in log messages for better debugging. It contrasts a good example with context (userId, action, timestamp) against a bad example lacking context. ```php // Good - includes relevant context $logger->info('User action', [ 'userId' => $userId, 'action' => 'profile_update', 'timestamp' => time() ]); // Bad - no context $logger->info('User did something'); ``` -------------------------------- ### Example Custom Event Implementation Source: https://github.com/sockeon/docs/blob/v2.0/api/event.md This example demonstrates how to create a custom event class `InventoryChanged` that implements `EventableContract`. It defines the event's name, payload, broadcast rooms, and namespace, and shows how to broadcast it using `Event::broadcast()`. ```php use Sockeon\Sockeon\Contracts\WebSocket\EventableContract; use Sockeon\Sockeon\Core\Event; final class InventoryChanged implements EventableContract { public function __construct( private readonly string $sku, private readonly int $available ) { } public function broadcastAs(): string { return 'inventory.changed'; } public function broadcastWith(): array { return [ 'sku' => $this->sku, 'available' => $this->available, 'time' => time(), ]; } public function broadcastOn(): ?array { return ['warehouse', 'admin']; } public function broadcastNamespace(): ?string { return '/inventory'; } } Event::broadcast(new InventoryChanged('SKU-123', 42)); ```