### 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));
```