A lightweight WebSocket server written in C++ with both standalone binary and PHP extension support. Features a beautiful Tailwind CSS chat UI and supports Cloudflare Tunnel for public access.
- 🚀 Standalone Binary - Run without PHP, no dependencies on shared hosting
- 🐘 PHP Extension - Use in PHP with
new WSocket(port)syntax - 💬 Built-in Chat UI - Beautiful Tailwind CSS chat room served via HTTP
- 🔄 Event System - Socket.IO-like
emit/onpattern - 🌐 Cloudflare Tunnel - Works with
wss://through tunnels - 👥 User Tracking - Online count, join/leave notifications
- 📡 Event Forwarding - Broadcast or send to specific clients
- g++ with C++17 support
- OpenSSL development headers (
libssl-dev)
- PHP 8.x with development headers (
php-dev) - PHP-CPP library (
libphpcpp)
# Build everything (PHP extension + standalone binary)
make
# Build only standalone binary
make wsocket
# Build static binary (for shared hosting without OpenSSL)
make static# Start server on port 8080
./wsocket 8080
# Open in browser
# http://localhost:8080The server automatically serves client.html when accessed via HTTP browser.
# Terminal 1: Start server
./wsocket 8080
# Terminal 2: Create tunnel
cloudflared tunnel --url http://localhost:8080
# Access via the tunnel URL (e.g., https://xxx.trycloudflare.com)<?php
// Create server (singleton per port)
$ws = new WSocket(8080);
// Event handlers
$ws->onConnect(function($clientId) {
echo "Client $clientId connected\n";
});
$ws->onMessage(function($clientId, $message) use ($ws) {
$ws->broadcast("Client $clientId: $message");
});
// Start server
$ws->start();
// Messaging
$ws->emit('notification', '{"message":"Hello!"}'); // To all
$ws->emitTo(1, 'private', '{"text":"Hi"}'); // To specific client
$ws->broadcast('Raw message to all');
// Get info
echo $ws->getClientCount();
print_r($ws->getClientIds());When running the standalone server, use these commands:
| Command | Description |
|---|---|
emit <event> <json> |
Emit event to all clients |
broadcast <message> |
Send raw message to all |
sendto <id> <message> |
Send to specific client |
emitto <id> <event> <json> |
Emit to specific client |
clients |
Show connected clients |
quit |
Stop server |
Events are JSON messages:
// Send event (browser)
ws.send(JSON.stringify({
event: 'chat',
data: { message: 'Hello!' },
to: 2 // Optional: specific client ID
}));
// Receive event
ws.onmessage = (e) => {
const msg = JSON.parse(e.data);
// msg.event = 'chat'
// msg.data = { from: 1, payload: { message: 'Hello!' } }
};| Event | Direction | Description |
|---|---|---|
_connected |
Server → Client | Sent on connect with {clientId: N} |
_userCount |
Server → Client | Broadcast when user count changes |
├── common/
│ ├── wsocket_common.h # Shared WebSocket server header
│ └── wsocket_common.cpp # Shared implementation
├── wsocket_main.cpp # Standalone binary entry point
├── wsocket_php.cpp # PHP extension wrapper
├── client.html # Chat UI (served via HTTP)
├── Makefile
└── README.MD
| Command | Description |
|---|---|
make |
Build PHP extension + standalone binary |
make wsocket |
Build standalone binary only |
make static |
Build static binary (no dependencies) |
make install |
Install PHP extension |
make clean |
Remove built files |
For shared hosting without root access:
# Build static binary
make static
# Upload to server
scp wsocket-static client.html user@server:~/
# On server
chmod +x wsocket-static
./wsocket-static 8080start()- Start the serverstop()- Stop the serverisRunning()- Check if runninggetPort()- Get port number
broadcast(message)- Send raw message to allbroadcastExcept(message, excludeId)- Broadcast except one clientemit(event, data)- Emit event to allemitExcept(event, data, excludeId)- Emit except one clientsendTo(clientId, message)- Send to specific clientemitTo(clientId, event, data)- Emit to specific clientforwardEvent(fromId, event, data, toId)- Forward client event
getClientCount()- Get number of connected clientsgetClientIds()- Get array of client IDssetUsername(clientId, name)- Set client usernamegetUsername(clientId)- Get client username
onConnect(callback)- Handle new connectionsonDisconnect(callback)- Handle disconnectionsonMessage(callback)- Handle messages
setHttpContent(html)- Set HTML to serve on HTTP requests
MIT