#}
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.