Realtime
Environment-scoped pub/sub rooms over Socket.IO — emit from servers over HTTP, listen from apps, with optional payload schemas.
Rooms are named channels (orders:42, drivers:erbil). Apps join rooms over
a Socket.IO connection and listen for events; servers (or apps) emit events
into rooms. Rooms can be related — joining a parent joins its related rooms —
and can enforce a JSON payload schema.
Rooms are environment-scoped
The key that emits and the key that joins must belong to the same
environment. A mismatch doesn't error — the emit succeeds with zero
recipients. Check recipients when messages "just don't arrive".
Listening (apps)
final rt = Nexus.instance.realtime;
rt.connect(); // idempotent
await rt.join('orders:42'); // → {ok, room, related}
rt.on('status', (data) => setState(() => status = data['state']));
await rt.emit('orders:42', 'location', {'lat': 36.19, 'lng': 44.01});
await rt.leave('orders:42');
rt.off('status');Rooms and handlers survive reconnects. With manageRealtimeWithLifecycle
(default) the socket closes when the app is backgrounded — connection minutes are
billed — and reconnects, re-joining rooms, on foreground. autoConnectRealtime: true opens it at startup.
Emitting (servers)
Emitting is plain HTTP — no socket needed.
use Inverge\Nexus\RoomMessage;
$nexus->realtime()->emit('orders:42', 'status', ['state' => 'shipped']);
$nexus->realtime()->emit('orders:42', ['status', 'updated'], ['state' => 'shipped']); // several events
$nexus->realtime()->emitToRooms(['a', 'b'], 'ping', ['n' => 1]);
$nexus->realtime()->broadcast([
new RoomMessage('room:a', ['ping'], ['n' => 1]),
new RoomMessage('room:b', ['ping'], ['n' => 2]),
]);Room registry, relations & schemas
room = client.realtime.register_room("orders", type="standard")
client.realtime.link(room_id, related_id) # joining room_id also joins related_id
client.realtime.set_schema(room_id, {"type": "object", "required": ["state"]})
client.realtime.enable_schema(room_id, True) # attaching a schema ≠ enforcing itWhen a schema is enabled, emits whose payload doesn't validate are rejected. Joining a room also joins every room related to it — keep per-user rooms out of relations with shared rooms, or every member receives every user's events.
Sessions & billing
A connection authenticates with the API key and the current identity, so it joins the person's session and keeps it alive. Connection minutes and delivered messages are metered — see Usage & billing.
