phrity/websocket
PHP WebSocket client and multi-connection server with ws/wss support. Includes listener callbacks, standard Close and Ping/Pong handling, optional deflate compression, fragmentation and masking support, plus middleware system for extending behavior.
Pros:
Detach connection on failed handshake), reducing implicit state leaks.Cons:
receive() method remains blocking. The handshake fix doesn’t resolve this, but it mitigates one source of connection leaks.Laravel Stack Fit:
Dependencies:
ext-sockets, ext-zlib). The fix is self-contained and doesn’t introduce conflicts with Laravel’s async libraries.Laravel Client Integration:
// app/Jobs/SendWebSocketMessage.php
class SendWebSocketMessage implements ShouldQueue {
public function handle() {
$client = new WebSocket\Client("wss://example.com");
try {
$client->text($this->message)->start(); // Handshake failures now detach cleanly
} catch (ConnectionException $e) {
Log::error("WebSocket handshake failed: " . $e->getMessage());
}
}
}
Laravel Server Integration:
// app/Services/WebSocketServerService.php
class WebSocketServerService {
public function start() {
$server = new WebSocket\Server();
$server->onOpen(function ($connection) {
// Handshake is now guaranteed to succeed or detach
Auth::validateOrReject($connection->getMeta('handshake.headers'));
});
$server->start();
}
}
beyondcode/laravel-websockets) benefit from reduced connection leaks.Middleware Integration:
// app/Http/Middleware/ValidateWebSocketToken.php
class ValidateWebSocketToken {
public function __invoke($request, $next) {
if (!$request->hasWebSocketToken()) {
$request->connection->close(4001, 'Invalid token'); // Detaches cleanly
return;
}
return $next($request);
}
}
ConnectionException events to audit handshake failures during migration.PingResponder) remain compatible, but their error handling may now rely on detached connections.ConnectionException to track handshake failures:
$server->onError(function ($server, $connection, $code, $message) {
Log::warning("WebSocket error [$code]: $message");
});
"Failed handshakes now detach connections immediately. Custom middleware must handle
ConnectionExceptionfor graceful fallbacks."
# Monitor detached connections in Laravel Tinker
$server->getConnections()->filter(fn($conn) => $conn->isDetached())->count();
$server->onError(function ($server, $connection, $code) {
if ($code === 1002) { // Protocol error (e.g., malformed frame)
$connection->close(1008, 'Policy violation');
}
});
"Connections now detach on handshake failures. Test your middleware’s error paths with the new behavior."
public function testFailedHandshakeDetachesConnection() {
$server = new WebSocket\Server();
$server->onOpen(function () { throw new Exception('Auth failed'); });
$server->start();
$this->assertCount(0, $server->getConnections()); // No orphaned connections
}
How can I help you explore Laravel packages today?