ez-php / websocket-tls
TLS/WSS termination for ez-php/websocket — an ssl:// listener and Fiber event loop that hands negotiated connections to the plain WebSocket server's Connection/HandlerInterface.
Requires
- php: ^8.5
- ext-openssl: *
- ez-php/websocket: ^2.6.2
Requires (Dev)
- ez-php/docker: ^2.6.0
- friendsofphp/php-cs-fixer: ^3.94
- phpstan/phpstan: ^2.1
- phpstan/phpstan-deprecation-rules: ^2.0
- phpstan/phpstan-strict-rules: ^2.0
- phpunit/phpunit: ^13.0
Suggests
None
Provides
None
Conflicts
None
Replaces
None
README
TLS/WSS termination for ez-php/websocket — a tcp:// listener carrying the certificate and a Fiber event loop that hands negotiated connections to the plain WebSocket server's Connection/HandlerInterface.
Installation
composer require ez-php/websocket-tls
Usage
use EzPhp\WebsocketTls\TlsServer; $server = new TlsServer( host: '0.0.0.0', port: 8443, certFile: '/etc/ssl/certs/example.com.pem', keyFile: '/etc/ssl/private/example.com.key', // optional: subprotocols: ['graphql-transport-ws'] — negotiated like the plain Server // optional: compression: new PerMessageDeflateConfig() — permessage-deflate, as on the plain Server ); $server->run(new MyHandler()); // implements EzPhp\WebSocket\HandlerInterface, blocks until interrupted
MyHandler is the same EzPhp\WebSocket\HandlerInterface implementation you would
write for the plain-TCP ez-php/websocket Server — nothing about the RFC 6455
handshake, frame codec, or connection lifecycle changes. TlsServer only replaces
how the underlying TCP socket is created and terminates the TLS layer before
handing the plaintext stream to ez-php/websocket's Connection.
For most deployments, terminating TLS at a reverse proxy (nginx, Caddy) in front
of a plain ez-php/websocket Server is simpler and still the recommended path.
Reach for this package when a reverse proxy isn't available in front of the
WebSocket process itself.
Loop hooks
$server->hooks() returns the same EzPhp\WebSocket\LoopHooks as the plain
Server (ez-php/websocket 2.6+), so other code can join the TLS event loop:
$hooks = $server->hooks(); // Watch an extra socket (e.g. a Redis Pub/Sub connection) for readability. $hooks->addReadStream($redisSocket, function ($stream): void { // read from $stream without blocking }); // Run on every loop iteration (about every 50 ms) — timers, timeouts. $hooks->onTick(function (): void { // ... }); $server->run(new MyHandler());
ez-php/graphql-subscriptions uses both: its Redis relay registers its subscriber
socket, and GraphQLTransportWsHandler::tick() enforces the connection-init timeout.
License
MIT