erfanvahabpour / laravel-swoole-ws
Laravel WebSocket server built on Swoole/OpenSwoole with routing, command protocols, scoped connections, channels, and Redis/Table-backed connection stores.
Installs: 31
Dependents: 0
Suggesters: 0
Security: 0
Stars: 1
Watchers: 0
Forks: 0
Open Issues: 0
pkg:composer/erfanvahabpour/laravel-swoole-ws
Requires
- php: ^8.2
- illuminate/console: ^10.0|^11.0|^12.0
- illuminate/support: ^10.0|^11.0|^12.0
Requires (Dev)
- orchestra/testbench: ^9.0|^10.0
- phpunit/phpunit: ^10.0|^11.0
README
A high-performance WebSocket server library for Laravel powered by Swoole / OpenSwoole, designed for:
- Real-time applications
- IoT / device communication
- Command-based device protocols
- Channel & room broadcasting
- Scalable multi-connection state management (memory / table / Redis)
This package provides a Laravel-native DX while running outside the HTTP lifecycle.
โ ๏ธ Status: Under active development APIs are stabilizing, but breaking changes may occur.
โจ Features (at a glance)
Core
- ๐ Swoole / OpenSwoole WebSocket server
- ๐ Laravel service provider & facade
- ๐งญ WebSocket routing (
WS::route) - ๐ง Command-based device protocol (
WS::command,WS::response) - ๐ Handshake URL path scoping (
/pub/chat,/attendance, etc.)
Security & Middleware
- ๐ Middleware support (
ws.auth, custom middleware) - ๐ฅ Channels & presence authorization
Messaging
- ๐ก Broadcast to rooms / users
- ๐งฉ Scoped command routing
State & Scaling
-
๐ Connection stores:
- In-memory
- Swoole\Table
- Redis (multi-server ready)
Tooling
- โ๏ธ Artisan commands (
ws:start,ws:stop,ws:reload,ws:list) - ๐งช Testbench + PHPUnit support
๐ฆ Requirements
- PHP 8.2+
- Laravel 10+
- Swoole or OpenSwoole extension enabled
php -m | grep swoole php -m | grep openswoole
๐ฅ Installation
composer require erfanvahabpour/laravel-swoole-ws
Laravel auto-discovery is enabled.
๐ Publish Config & Routes
php artisan vendor:publish --tag=ws-config php artisan vendor:publish --tag=ws-routes php artisan vendor:publish --tag=ws-channels
Creates:
config/ws.phproutes/ws.phproutes/ws_channels.php
โถ๏ธ Starting the WebSocket Server
php artisan ws:start
WS server starting on 0.0.0.0:9502
Stop / reload:
php artisan ws:stop php artisan ws:reload
โน๏ธ On every
ws:start, the server clears the active connection index to prevent stale connections from appearing inws:list.
โ๏ธ Artisan Commands
php artisan ws:start php artisan ws:stop php artisan ws:reload php artisan ws:list
ws:list
Lists active WebSocket connections.
Example:
+---+----+-------------+-----------+------------+
| # | FD | Scope | User | Connected |
+---+----+-------------+-----------+------------+
| 1 | 12 | /pub/chat | guest | 2m 14s |
| 2 | 18 | /attendance| user#42 | 12m 03s |
+---+----+-------------+-----------+------------+
Options:
php artisan ws:list --count php artisan ws:list --json
โน๏ธ With Swoole\Table,
ws:listreflects only the current WS process. Use Redis for cross-process visibility.
๐ WebSocket Protocols Supported
This library supports two protocols simultaneously.
1๏ธโฃ Legacy Route Protocol (WS::route)
Client โ Server
{
"path": "/chat",
"action": "send",
"data": { "text": "hello" },
"meta": {}
}
Route
WS::route('/chat', 'send', function ($ctx, $data) { return ['ok' => true]; });
2๏ธโฃ Command / Device Protocol (WS::command)
Designed for IoT / terminal / attendance devices.
Client โ Server
{
"cmd": "reg",
"sn": "ABC123",
"version": "1.0"
}
Server โ Client
{
"ret": "reg",
"result": true,
"cloudtime": "2025-01-01 12:00:00"
}
๐ Handshake Path Scoping
Devices can connect using different URLs:
ws://127.0.0.1:9502/pub/chat
ws://127.0.0.1:9502/attendance
Each path becomes a routing scope, allowing the same command names with different logic.
๐งญ Scoped Command Routing
WS::scope('/pub/chat')->command('reg', fn ($ctx, $payload) => ['pong' => true]); WS::scope('/attendance')->command('reg', function ($ctx, $payload) { return [ 'device' => 'attendance', 'sn' => $payload['sn'] ?? null, ]; });
๐ Automatic Replies
Returning an array automatically sends:
{ "ret": "<cmd>", "result": true, ... }
Manual reply:
$ctx->replyRet('reg', true, ['cloudtime' => now()]);
๐ Connection Lifecycle Helpers
$ctx->isEstablished(); $ctx->disconnect(); $ctx->disconnectAndForget();
Use disconnectAndForget() for:
- kicking users
- invalid devices
- admin disconnects
๐ Middleware & Authentication
- Built-in:
ws.auth - Handshake token:
?token=TOKEN - Message token:
{ "meta": { "auth": "TOKEN" } }
Custom resolver:
config()->set('ws.auth.resolver', fn ($token) => (object)['id' => 1]);
๐ก Channels & Presence
WS::channel('private-chat.{id}', fn ($user, $id) => true);
๐ Connection Stores
memoryโ simple, single workertableโ fast shared memoryredisโ recommended for scaling & CLI introspection
๐งช Testing & CI
vendor/bin/phpunit
- PHP 8.2 / 8.3
- PHPUnit
- GitHub Actions
๐บ Roadmap
- WebSocket routing
- Command protocol
- Scoped connections
- Presence broadcasting
- Rate limiting
- Metrics endpoint
- Binary protocol support
License
MIT ยฉ Erfan Vahabpour