feat(cluster): centralize cluster/broadcast event for UDP CLUSTER_EVENT send

Register core handler ctx.on("cluster/broadcast") in ClusterManager to send CLUSTER_EVENT via subnet-directed UDP broadcast; services now delegate broadcasting by firing this event. Fix lambda to reference this->ctx inside handler. Update NeoPatternService to fire cluster/broadcast with event JSON instead of sending UDP directly. Improves consistency and removes duplicated UDP code in services.
This commit is contained in:
2025-09-28 13:35:42 +02:00
parent 8da9f77441
commit f4ccb1c7ef
2 changed files with 22 additions and 10 deletions

View File

@@ -154,7 +154,7 @@ void NeoPatternService::handleControlRequest(AsyncWebServerRequest* request) {
updated = true;
}
// Broadcast to peers if requested
// Broadcast to peers if requested (delegate to core broadcast handler)
if (broadcast && any) {
JsonDocument eventDoc;
eventDoc["event"] = "api/neopattern";
@@ -163,15 +163,10 @@ void NeoPatternService::handleControlRequest(AsyncWebServerRequest* request) {
String eventJson;
serializeJson(eventDoc, eventJson);
// Compute subnet-directed broadcast to improve delivery on some networks
IPAddress ip = WiFi.localIP();
IPAddress mask = WiFi.subnetMask();
IPAddress bcast(ip[0] | ~mask[0], ip[1] | ~mask[1], ip[2] | ~mask[2], ip[3] | ~mask[3]);
LOG_INFO("NeoPattern", String("Broadcasting CLUSTER_EVENT api/neopattern to ") + bcast.toString() + " payloadLen=" + String(payloadStr.length()));
ctx.udp->beginPacket(bcast, ctx.config.udp_port);
String msg = String(ClusterProtocol::CLUSTER_EVENT_MSG) + ":" + eventJson;
ctx.udp->write(msg.c_str());
ctx.udp->endPacket();
LOG_INFO("NeoPattern", String("Submitting cluster/broadcast for api/neopattern payloadLen=") + String(payloadStr.length()));
std::string ev = "cluster/broadcast";
String eventStr = eventJson;
ctx.fire(ev, &eventStr);
}
// Return current state

View File

@@ -8,6 +8,23 @@ ClusterManager::ClusterManager(NodeContext& ctx, TaskManager& taskMgr) : ctx(ctx
NodeInfo* node = static_cast<NodeInfo*>(data);
this->addOrUpdateNode(node->hostname, node->ip);
});
// Centralized broadcast handler: services fire 'cluster/broadcast' with CLUSTER_EVENT JSON payload
ctx.on("cluster/broadcast", [this](void* data) {
String* jsonStr = static_cast<String*>(data);
if (!jsonStr) {
LOG_WARN("Cluster", "cluster/broadcast called with null data");
return;
}
// Subnet-directed broadcast (more reliable than 255.255.255.255 on some networks)
IPAddress ip = WiFi.localIP();
IPAddress mask = WiFi.subnetMask();
IPAddress bcast(ip[0] | ~mask[0], ip[1] | ~mask[1], ip[2] | ~mask[2], ip[3] | ~mask[3]);
LOG_INFO("Cluster", String("Broadcasting CLUSTER_EVENT to ") + bcast.toString() + " len=" + String(jsonStr->length()));
this->ctx.udp->beginPacket(bcast, this->ctx.config.udp_port);
String msg = String(ClusterProtocol::CLUSTER_EVENT_MSG) + ":" + *jsonStr;
this->ctx.udp->write(msg.c_str());
this->ctx.udp->endPacket();
});
// Register tasks
registerTasks();
initMessageHandlers();