textalk/websocket
Archived, unmaintained WebSocket client and rudimentary single-connection server for PHP. Provides low-level read/write over WebSocket streams with handshake, close, and ping/pong support. No listeners, threading, or request association.
Install the package:
composer require textalk/websocket
Ensure your PHP version is ^7.4|^8.0 (or use older versions for legacy support).
Basic Client Usage (connect to a public WebSocket server):
use WebSocket\Client;
$client = new Client("wss://echo.websocket.org");
$client->text("Hello WebSocket!");
echo $client->receive(); // Outputs: "Hello WebSocket!"
$client->close();
Basic Server Usage (run a single-threaded WebSocket server):
use WebSocket\Server;
$server = new Server();
$server->accept(); // Blocks until a connection is established
$message = $server->receive();
$server->text("Echo: " . $message);
$server->close();
Run the server (e.g., via Artisan command):
// In a Laravel Artisan command
public function handle() {
$server = new Server();
$server->accept();
while (true) {
$message = $server->receive();
$server->text("Server received: " . $message);
}
}
Test locally using a WebSocket client tool (e.g., WebSocket King) or wscat:
npm install -g wscat
wscat -c ws://localhost:8080
Create a Laravel Job to send WebSocket messages:
use WebSocket\Client;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
class SendNotificationJob implements ShouldQueue
{
public function handle() {
$client = new Client(env('WEBSOCKET_NOTIFICATION_URL'));
$client->text(json_encode(['type' => 'notification', 'message' => 'Hello!']));
$client->close();
}
}
Dispatch the job when an event occurs (e.g., user login):
SendNotificationJob::dispatch();
Client-side: Use JavaScript to listen for WebSocket messages (e.g., with EventSource or a custom WebSocket client).
Connection Management:
Client for persistent connections (e.g., chat apps, live updates).try-catch for ConnectionException or TimeoutException.try {
$client = new Client("wss://example.com/ws");
while (true) {
$message = $client->receive();
// Process message
}
} catch (ConnectionException $e) {
// Reconnect logic
$client = new Client("wss://example.com/ws");
}
Message Handling:
text(), binary(), ping(), or pong() for sending.$message = $client->receive(WebSocket\Opcode::TEXT);
Async Operations:
dispatch(new SendWebSocketMessageJob($message));
Single-Threaded Server:
$server = new Server();
$server->accept();
while (true) {
$message = $server->receive();
$server->text("Echo: " . $message);
}
Multi-Connection Handling:
// Pseudocode for multi-connection (not production-ready)
$servers = [];
while (true) {
$server = new Server();
$servers[] = $server;
go(function() use ($server) {
$server->accept();
while (true) {
$message = $server->receive();
$server->text("Echo: " . $message);
}
});
}
Service Provider: Bind the WebSocket client/server to the container for dependency injection:
// app/Providers/WebSocketServiceProvider.php
public function register() {
$this->app->singleton('websocket.client', function() {
return new Client(env('WEBSOCKET_URL'));
});
}
Middleware: Use middleware to validate WebSocket connections (e.g., auth):
$server = new Server();
$server->accept();
$token = $server->getHeader('Authorization');
if (!auth()->validateToken($token)) {
$server->close(1008, "Unauthorized");
return;
}
Event Broadcasting: Replace Laravel’s default broadcasting with a custom WebSocket solution:
// app/Providers/EventServiceProvider.php
public function boot() {
Event::listen('user.logged_in', function($user) {
$client = app('websocket.client');
$client->text(json_encode(['event' => 'user.logged_in', 'user' => $user->id]));
});
}
Client-Side: Handle common exceptions:
try {
$client = new Client("ws://invalid.url");
} catch (ConnectionException $e) {
Log::error("WebSocket connection failed: " . $e->getMessage());
// Fallback to HTTP polling
}
Server-Side: Validate messages and close connections gracefully:
$message = $server->receive();
if (strlen($message) > 1024) {
$server->close(1009, "Message too large");
return;
}
// Dispatch a job to send a WebSocket message
SendWebSocketMessage::dispatch($message);
// Job implementation
public function handle() {
$client = new Client(env('WEBSOCKET_URL'));
$client->text($this->message);
$client->close();
}
use React\EventLoop\Factory;
use React\Socket\ConnectionInterface;
$loop = Factory::create();
$server = new React\Socket\SocketServer('0.0.0.0:8080', [], $loop);
$server->on('connection', function (ConnectionInterface $conn) {
$websocket = new WebSocket\Server($conn);
$websocket->accept();
$websocket->on('message', function($msg) use ($websocket) {
$websocket->text("Echo: " . $msg);
});
});
$loop->run();
// Publisher (Laravel)
Redis::publish('websocket_channel', json_encode($message));
// Subscriber (WebSocket Server)
$redis = new Redis();
$redis->subscribe(['websocket_channel'], function($message) use ($server) {
$server->text($message);
});
// Client with SSL
$context = stream_context_create([
'ssl' => [
'verify_peer' => false, // Disable for self-signed certs (not recommended for production)
'allow_self_signed' => true,
]
]);
$client = new Client("wss://example.com/ws", [], $context);
// Server with SSL (requires a certificate)
$server = new Server('ssl://0.0.0.0
How can I help you explore Laravel packages today?