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

v0.1.5 2026-01-04 10:28 UTC

This package is auto-updated.

Last update: 2026-01-04 10:59:11 UTC


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.php
  • routes/ws.php
  • routes/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 in ws: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:list reflects 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 worker
  • table โ€“ fast shared memory
  • redis โ€“ 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