#}

API WebSocket Guide

Build real-time bidirectional communication with OpenSwoole WebSocket server

WebSocket Guide

Overview

GEMVC provides a powerful WebSocket implementation through OpenSwoole's SwooleWebSocketHandler class, enabling real-time bidirectional communication.

Bidirectional Full-duplex communication
Low Latency Persistent connections
JWT Auth Token-based security
Rate Limiting Built-in protection
info: WebSocket requires OpenSwoole. Not available with Apache/PHP-FPM.

Server Setup

Configure your WebSocket server in the OpenSwoole bootstrap:

Server Configuration
use Gemvc\Swoole\OpenSwooleServer;

$server = new OpenSwooleServer();

// Enable WebSocket
$server->enableWebSocket();

// Set WebSocket handler
$server->setWebSocketHandler(new MyWebSocketHandler());

// Start server
$server->start();

WebSocket Handler

Create a handler by extending SwooleWebSocketHandler:

WebSocket Handler
use Gemvc\Swoole\SwooleWebSocketHandler;

class MyWebSocketHandler extends SwooleWebSocketHandler
{
    /**
     * Called when a client connects
     */
    public function onOpen($server, $request): void
    {
        $fd = $request->fd;
        echo "Client {$fd} connected\n";
        
        // Subscribe to a channel
        $this->subscribeToChannel($fd, 'general');
    }
    
    /**
     * Called when a message is received
     */
    public function onMessage($server, $frame): void
    {
        $data = json_decode($frame->data, true);
        
        switch ($data['action'] ?? '') {
            case 'broadcast':
                $this->broadcastToChannel('general', [
                    'type' => 'message',
                    'content' => $data['message']
                ]);
                break;
                
            case 'private':
                $this->sendToClient($data['to'], [
                    'type' => 'private',
                    'from' => $frame->fd,
                    'content' => $data['message']
                ]);
                break;
        }
    }
    
    /**
     * Called when a client disconnects
     */
    public function onClose($server, $fd): void
    {
        echo "Client {$fd} disconnected\n";
        $this->unsubscribeFromAllChannels($fd);
    }
}

Available Methods

Method Description
subscribeToChannel($fd, $channel)Add client to a channel
unsubscribeFromChannel($fd, $channel)Remove client from channel
broadcastToChannel($channel, $data)Send to all clients in channel
sendToClient($fd, $data)Send to specific client
broadcastToAll($data)Send to all connected clients
getChannelClients($channel)Get all clients in a channel

Client-Side Connection

JavaScript Client
// JavaScript WebSocket client
const ws = new WebSocket('wss://api.example.com/ws');

// Connection opened
ws.onopen = () => {
    console.log('Connected to WebSocket server');
    
    // Send a message
    ws.send(JSON.stringify({
        action: 'broadcast',
        message: 'Hello everyone!'
    }));
};

// Listen for messages
ws.onmessage = (event) => {
    const data = JSON.parse(event.data);
    console.log('Received:', data);
};

// Connection closed
ws.onclose = (event) => {
    console.log('Disconnected:', event.code, event.reason);
};

// Error handling
ws.onerror = (error) => {
    console.error('WebSocket error:', error);
};

Authentication

Authenticate WebSocket connections using JWT tokens:

JWT Authentication
public function onOpen($server, $request): void
{
    // Get token from query string or header
    $token = $request->get['token'] ?? null;
    
    if (!$token || !$this->validateJWT($token)) {
        // Reject unauthenticated connection
        $server->disconnect($request->fd, 4001, 'Unauthorized');
        return;
    }
    
    // Store user info for this connection
    $this->setConnectionData($request->fd, [
        'user_id' => $this->getUserIdFromToken($token)
    ]);
}
Tip: Always validate JWT tokens on WebSocket connections to prevent unauthorized access.

Next Steps