Documents centralized cluster broadcasting: service -> ctx.fire("cluster/broadcast", eventJson) -> UDP CLUSTER_EVENT -> peer ctx.fire(event, data). Includes message format, service/core responsibilities, logging, networking notes, and troubleshooting.
3.2 KiB
3.2 KiB
Cluster Broadcast (CLUSTER_EVENT)
Overview
Spore supports cluster-wide event broadcasting via UDP. Services publish a local event, and the core broadcasts it to peers as a CLUSTER_EVENT. Peers receive the event and forward it to local subscribers through the internal event bus.
- Local trigger:
ctx.fire("cluster/broadcast", eventJson) - UDP message:
CLUSTER_EVENT:{json} - Receiver action: Parses
{json}and callsctx.fire(event, data)
This centralizes network broadcast in core, so services never touch UDP directly.
Message format
- UDP payload prefix:
CLUSTER_EVENT: - JSON body:
{
"event": "<event-name>",
"data": "<json-string>" // or an inline JSON object/array
}
Notes:
- The receiver accepts
dataas either a JSON string or a nested JSON object/array. Nested JSON is serialized back to a string before firing the local event. - Keep payloads small (UDP, default buffer 512 bytes).
Core responsibilities
ClusterManagerregisters a centralized handler:- Subscribes to
cluster/broadcastto send the provided event JSON over UDP broadcast. - Listens for incoming UDP
CLUSTER_EVENTmessages and forwards them to local subscribers viactx.fire(event, data).
- Subscribes to
- Broadcast target uses subnet-directed broadcast (e.g.,
192.168.1.255) for better reliability. Both nodes must share the sameudp_port.
Service responsibilities
Services send and receive events using the local event bus.
- Subscribe to an event name and apply state from
data:
ctx.on("api/neopattern", [this](void* dataPtr) {
String* jsonStr = static_cast<String*>(dataPtr);
if (!jsonStr) return;
JsonDocument doc;
if (deserializeJson(doc, *jsonStr)) return;
JsonObject obj = doc.as<JsonObject>();
// Parse and apply fields from obj
});
- Build a control payload and update locally via the same event:
JsonDocument payload;
payload["pattern"] = "rainbow_cycle"; // example
payload["brightness"] = 100;
String payloadStr; serializeJson(payload, payloadStr);
ctx.fire("api/neopattern", &payloadStr);
``;
3) Broadcast to peers by delegating to core:
```cpp
JsonDocument envelope;
envelope["event"] = "api/neopattern";
envelope["data"] = payloadStr; // JSON string
String eventJson; serializeJson(envelope, eventJson);
ctx.fire("cluster/broadcast", &eventJson);
With this flow, services have a single codepath for applying state (the event handler). Broadcasting simply reuses the same payload.
Logging
- Core logs source IP, payload length, and event name for received
CLUSTER_EVENTs. - Services can log when submitting
cluster/broadcastand when applying control events.
Networking considerations
- Ensure all nodes:
- Listen on the same
udp_port. - Are in the same subnet (for subnet-directed broadcast).
- Listen on the same
- Some networks may block global broadcast (
255.255.255.255). Subnet-directed broadcast is used by default.
Troubleshooting
- If peers do not react:
- Confirm logs show
CLUSTER_EVENT raw from <ip>on the receiver. - Verify UDP port alignment and WiFi connection/subnet.
- Check payload size (<512 bytes by default) and JSON validity.
- Ensure the service subscribed to the correct
eventname and handlesdata.
- Confirm logs show