Method
Swerve::publish
Send a message to every subscriber of $topic, in every worker process of this swerve, this one included.
Description#
public static Swerve::publish(
string $topic,
mixed $message
): voidReturns once the message is on its way, not once delivered, and never suspends the caller,
even the first time this worker publishes to $topic: safe to call from a finally,
including one that runs after the coroutine was cancelled (a WebSocket handler's goodbye).
Delivery is at most once, to the subscriptions that exist when the message reaches their
worker: there is no history, and a worker starting later (after a reload, a recycle, a
crash) sees nothing sent before. The messages of one publishing worker arrive in the order
it published them, with no order between workers. A worker that does not read its inbox
loses the messages sent to it after 0.1 s. Swerve embedded without its master process
delivers in this process only.
Every message travels as JSON: encoded once here, decoded once in each worker, and every
subscriber gets the value published, shared: a string stays a string ('{}' too), a list an
array, and an object (an array with keys) a read-only SealedObject:
$message->end.
Parameters#
- $topic string
- 1 to 255 bytes
- $message mixed
- Anything
json_encode()takes except null; at most 128 KiB encoded
Errors / Exceptions#
| Exception | When |
|---|---|
InvalidArgumentException | For a topic or message outside those sizes, a topic starting with "\0", or null (which a heartbeat subscription yields for "nothing came") |
LogicException | Directly in swerve.php, which the worker serves after: a coroutine started there waits instead |
JsonException | For a value JSON can't express |
Examples#
use Swerve\Swerve;
phasync::run(function () {
// Two subscribers, as two requests in a worker would have
foreach (['ann', 'bob'] as $name) {
$subscription = Swerve::subscribe('game'); // subscribed now, not at the foreach
phasync::go(function () use ($subscription, $name) {
foreach ($subscription as $message) {
echo "$name got ", json_encode($message), "\n";
if ('end' === $message) {
break;
}
}
});
}
Swerve::publish('game', ['type' => 'score', 'player' => 7, 'points' => 10]);
Swerve::publish('game', [7, 'kill']);
Swerve::publish('game', 'end');
});ann got {"type":"score","player":7,"points":10}
bob got {"type":"score","player":7,"points":10}
ann got [7,"kill"]
bob got [7,"kill"]
ann got "end"
bob got "end"Swerve::publish('game', ['kill', $playerId]);
Swerve::publish('game', ['type' => 'score', 'player' => $playerId, 'points' => 10]);See also#
Swerve::subscribeReceives the messagesSwerve::publishRawBytes that are not JSON, such as a binary WebSocket frameOrderedChannelWhen order between workers matters