Method
Swerve::publishRaw
Send $bytes unchanged to every subscriber of $topic, in every worker process of this swerve, this one included.
Description#
public static Swerve::publishRaw(
string $topic,
string $bytes
): voidFor messages Swerve::publish cannot carry: bytes that are not valid UTF-8, such as
a binary WebSocket frame, which publish() would fail to encode as JSON. A subscriber gets
exactly $bytes, as a plain string, never decoded. The same delivery guarantees as
publish() apply (order, at-most-once, never suspends the caller, and the rest); see its
docblock. A topic may mix publish() and publishRaw() messages: each subscriber gets
each one in its own shape.
Parameters#
- $topic string
- 1 to 255 bytes
- $bytes string
- Any bytes, including none; at most 128 KiB
Errors / Exceptions#
| Exception | When |
|---|---|
InvalidArgumentException | For a topic or message outside those sizes, or a topic starting with "\0" |
LogicException | Directly in swerve.php, which the worker serves after: a coroutine started there waits instead |
Examples#
use Swerve\ClientRequest;
use Swerve\RequestHandler;
use Swerve\Swerve;
use Swerve\WebSocket;
// Binary WebSocket frames, forwarded to every worker's subscribers: publish() would fail to
// encode them as JSON, since a binary frame is not valid UTF-8.
$app = new RequestHandler(function (ClientRequest $request) {
WebSocket::from($request, function (WebSocket $ws) {
$ws->onMessage->listen(function (string $data, bool $binary) {
if ($binary) {
Swerve::publishRaw('frames', $data); // to this and every other worker
}
});
foreach (Swerve::subscribe('frames') as $frame) { // what this and every other connection sent
$ws->sendBinary($frame);
}
});
});
if (debug_backtrace()) {
return $app; // swerve loads this file: it is the application's swerve.php
}
// Run directly: serve the application, send one binary frame, and print what comes back
require __DIR__ . '/../serve.php';
[$swerve, $addr] = swerve_start(__FILE__);
try {
$connection = stream_socket_client("tcp://$addr", $errno, $error, 5);
fwrite($connection, "GET /frames HTTP/1.1\r\nHost: example\r\nUpgrade: websocket\r\nConnection: Upgrade\r\n"
. "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\nSec-WebSocket-Version: 13\r\n\r\n");
$head = '';
while (!str_contains($head, "\r\n\r\n")) {
$head .= fread($connection, 1);
}
$mask = "\1\2\3\4";
$payload = pack('nN', 1, 42); // any bytes, not valid UTF-8
fwrite($connection, "\x82" . chr(0x80 | strlen($payload)) . $mask . ($payload ^ str_repeat($mask, 32)));
$head = fread($connection, 2);
$length = ord($head[1]) & 0x7F;
echo 'sent ', bin2hex($payload), ', got back ', bin2hex((string) fread($connection, $length)), "\n";
fclose($connection);
} finally {
swerve_stop($swerve, false);
}Output
sent 00010000002a, got back 00010000002a
Swerve::publishRaw('frames', $binaryWebSocketFrame);See also#
Swerve::subscribeReceives the messages, raw or notSwerve::publishFor a value JSON can carry