pogo / websocket
Pogo WebSocket Driver
Requires
- laravel/octane: 2.13.4
- pusher/pusher-php-server: ^7.2.7
Requires (Dev)
- friendsofphp/php-cs-fixer: ^3.92.3
- mockery/mockery: ^1.6.12
- phpstan/phpstan: ^2.1.33
- phpunit/phpunit: ^12.5.4
- dev-main
- 0.0.4
- v0.0.3
- v0.0.2
- v0.0.1
- dev-renovate/github.com-caddyserver-caddy-v2-2.x
- dev-renovate/dunglas-frankenphp-1.x
- dev-renovate/github.com-dunglas-frankenphp-1.x
- dev-renovate/go-1.x
- dev-renovate/laravel-octane-2.x
- dev-renovate/github.com-redis-go-redis-v9-9.x
- dev-renovate/phpstan-packages
- dev-renovate/friendsofphp-php-cs-fixer-3.x-lockfile
- dev-renovate/phpunit-phpunit-12.x-lockfile
- dev-renovate/github.com-dunglas-frankenphp-caddy-digest
- dev-renovate/github.com-dunglas-frankenphp-digest
- dev-renovate/phpunit-phpunit-13.x
- dev-renovate/github.com-alicebob-miniredis-v2-2.x
This package is auto-updated.
Last update: 2026-03-08 18:46:31 UTC
README
Warning
This project is highly experimental, use with caution.
The Native, High-Performance Real-Time Solution for PHP.
- A Caddy module that embeds a scalable, Pusher-compatible WebSocket server directly into the FrankenPHP binary
- CGO-exported functions
pogo_websocket_publishandpogo_websocket_broadcast_multiallow PHP to broadcast messages instantly via shared memory. - The Caddy module uses FrankenPHP's
ExtensionWorkerAPI to invoke a dedicated pool of PHP threads for authentication, avoiding network overhead.
🚀 Features
- Pusher Protocol v7 Compliant: Supports Private & Presence channels, and User Authentication.
- High Performance: Benchmarked at 550+ messages/sec with sub-10ms latency on minimal hardware.
- Zero-Copy Broadcasts: Optimizes CPU usage by encoding messages once for thousands of clients.
- DoS Protection: Built-in Token Bucket Rate Limiting, Handshake Throttling, and Circuit Breakers for PHP Auth.
- Horizontal Scaling: Redis Pub/Sub support for multi-node clusters.
📦 Installation
Step 1: Build the Binary
Pre-built Binary or Docker (Recommended)
You can use the pre-compiled binaries or Docker images that already include the queue module.
- Binaries: Download from FrankenPHP with websocket, queue, and scheduler releases.
- Docker: Use the docker image.
Compile from Source
If you prefer to build it yourself, follow the instructions to install a ZTS version of libphp and xcaddy. Then, use xcaddy to build FrankenPHP with the pogo-queue module:
CGO_ENABLED=1 \ CGO_CFLAGS=$(php-config --includes) \ CGO_LDFLAGS="$(php-config --ldflags) $(php-config --libs)" \ xcaddy build \ --output frankenphp \ --with github.com/y-l-g/queue/module \ --with github.com/dunglas/frankenphp/caddy \ --with github.com/dunglas/caddy-cbrotli
Step 2: Install the Laravel Broadcast Driver
composer require pogo/websocket php artisan pogo:ws-install
⚙️ Configuration
Configure the module within your Caddyfile at the root of your laravel project (this exemple is an adapted copy of the octane Caddyfile, it will work with php artisan octane:frankenphp --caddyfile=Caddyfile).
{
frankenphp {
worker {
file "public/frankenphp-worker.php"
}
}
order pogo_websocket before php_server
}
:8080 {
log {
level info
}
format filter {
wrap json
fields {
uri query {
replace authorization REDACTED
}
}
}
route /app/* {
pogo_websocket {
app_id pogo-app
auth_path /pogo/auth
auth_script public/websocket-worker.php
webhook_secret super-secret-key
handshake_rate 100 # New connection attempts per second (Default: 100)
handshake_burst 50 # Burst allowance (Default: 50)
max_connections 10000 # Max concurrent clients
max_auth_body 16384 # Max PHP Auth response size (bytes)
max_concurrent_auth 100 # Max concurrent PHP Auth requests (DoS Protection)
num_workers 2 # Number of PHP workers dedicated to Auth
num_shards 8 # Internal sharding (Default: 2 * CPU Cores)
ping_period 54s # Server Ping interval
pong_wait 60s # Client Pong timeout
write_wait 10s # Socket write timeout
# redis_host localhost:6379
}
}
route {
root * public
encode zstd br gzip
php_server {
index frankenphp-worker.php
try_files {path} frankenphp-worker.php
resolve_root_symlink
}
}
}
Fill your .env
BROADCAST_CONNECTION=pogo WS_APP_ID=pogo-app WS_APP_SECRET=super-secret-key #needed for pusher client but not really sensitive i guess VITE_POGO_HOST=localhost #your site adress VITE_POGO_PORT=80 #your site port VITE_POGO_WSS_PORT=443 #your site port
Start octane (frankenphp must be compiled with pogo, use the dockerfile or the binary provided in this repo and put it in you bin folder).
php artisan octane:start --caddyfile=Caddyfile # or frankenphp run --caddyfile=Caddyfile # or frankenphp run --config Caddyfile
📊 Metrics
Prometheus metrics are available at http://localhost:2019/metrics (Caddy Admin):
| Metric | Type | Description |
|---|---|---|
pogo_websocket_connections_active |
Gauge | Active TCP connections. |
pogo_websocket_messages_total |
Counter | Total messages broadcasted. |
pogo_websocket_auth_failures_total |
Counter | Failed auths (labels: concurrency_limit, worker_error). |
pogo_websocket_circuit_breaker_open_total |
Counter | Requests rejected by Circuit Breaker. |
pogo_websocket_broker_dropped_total |
Counter | Messages dropped due to internal backpressure. |
pogo_websocket_subscriptions_total |
Counter | Total active subscriptions. |
pogo_websocket_auth_duration_seconds |
Histogram | Latency of the PHP Auth Worker. |
pogo_websocket_messages_dropped_total |
Counter | Messages dropped due to full client buffer. |
🛠 Troubleshooting
- 4100 Over Capacity: Increase
max_connectionsin Caddyfile. - 4009 Connection Unauthorized: Check
webhook_secretmatchesWS_APP_SECRET. - Too Many Requests: Tune
handshake_rateif legitimate traffic is being blocked.