relaystacks / conduit-php
Framework-agnostic Unix socket broadcaster for PHP. The transport core of the Conduit ecosystem.
Requires
- php: ^8.1
Requires (Dev)
None
Suggests
None
Provides
None
Conflicts
None
Replaces
None
This package is not auto-updated.
Last update: 2026-09-25 15:06:34 UTC
README
Framework-agnostic PHP transport for the RelayStacks Conduit broadcasting ecosystem.
Serializes broadcast messages as newline-delimited JSON, optionally signs them with HMAC-SHA256, and writes them to a Unix domain socket. The receiving end is the @relaystacks/conduit-echo Node.js relay server.
Zero framework dependencies — requires only PHP 8.1+.
Installation
composer require relaystacks/conduit-php
Quick Start
use RelayStacks\Conduit\UnixSocketTransport; $transport = new UnixSocketTransport( socketPath: '/home/user/laravel.sock', secret: 'your-shared-secret', // optional ); $success = $transport->send('chat-room', 'NewMessage', [ 'user' => 'Alice', 'text' => 'Hello!', ]);
API Reference
TransportInterface
The contract for all Conduit transports.
public function send(string $channel, string $event, array $data = []): bool;
| Param | Type | Description |
|---|---|---|
$channel |
string |
Channel name (e.g. presence-chat.1) |
$event |
string |
Broadcast event name |
$data |
array<string, mixed> |
Arbitrary event payload |
| Returns | bool |
true if the message was delivered |
UnixSocketTransport
The default (and only) transport implementation. Sends JSON frames over a Unix domain socket.
Constructor
| Param | Type | Default | Description |
|---|---|---|---|
$socketPath |
string |
(required) | Absolute path to the Unix socket file |
$timeout |
int |
2 |
Connect and write timeout in seconds |
$secret |
?string |
null |
Shared HMAC-SHA256 secret. null = unsigned messages |
Methods
send(string $channel, string $event, array $data = []): bool— Serialize and write the message. Returnstrueif the full frame was written.
ConduitException
Domain exception extending RuntimeException. Available for consumers to catch Conduit-specific errors.
HMAC Signing
When a $secret is provided, each message is signed with HMAC-SHA256:
- The body
{channel, event, data}is JSON-encoded once - The HMAC is computed over that exact string:
hash_hmac('sha256', $json, $secret) - The string is carried verbatim in the frame, alongside its signature
The verifier (conduit-echo) recomputes the HMAC over the body string exactly as it arrived. It never
re-encodes the body, so the two ends cannot disagree about escaping.
That distinction is the whole design. PHP's json_encode escapes / as \/ and non-ASCII as
\uXXXX unless told otherwise, and JavaScript's JSON.stringify does neither. Signing one encoding
and verifying against the other never matches, and the failure is silent — the receiver drops the
frame while the write that sent it reported success. Key ordering was never the risk; escaping is.
Frames signed this way are versioned with "v":2. Version 1 signed a re-encoded body and is still
accepted by the verifier for backward compatibility, but is no longer produced.
Wire Format
Each frame is a single line of JSON terminated by \n.
Unsigned:
{"channel":"chat-room","event":"NewMessage","data":{"user":"Alice","text":"Hello!"}}
Signed (v2):
{"v":2,"body":"{\"channel\":\"chat-room\",\"event\":\"NewMessage\",\"data\":{\"user\":\"Alice\",\"text\":\"Hello!\"}}","hmac":"a1b2c3..."}
body is a JSON string, not an object — it is signed and transmitted as the same bytes. A receiver
that parses it back into an object and re-serializes it is verifying a different string than the one
that was signed, which is exactly the v1 bug.
Use Without Laravel
This package works with any PHP framework or plain PHP scripts. For Laravel integration (broadcast driver, channel authorization, service provider), see relaystacks/laravel-conduit.
Requirements
- PHP >= 8.1
- Unix-like OS (Unix domain sockets are not available on Windows)
License
MIT