MQTT seems to work

1. subscribe now similar to HTTP server, with lambda
 2. subscribe topic syntax support all HTTP features as path arguments and wildcards
 3. event received() changed to receivedUnhandled() for unhandled messages (should never be called in proper work)
 4. internal logic got more complicated, several endpoints may be serviced by single MQTT topic, so nested Map used
This commit is contained in:
2026-05-28 20:26:49 +03:00
parent 236896fb0f
commit 38d09e272c
3 changed files with 261 additions and 56 deletions
+67 -44
View File
@@ -19,63 +19,86 @@ MessageMutable createMessage(Code c, const char * path, const MessageConst & msg
return MessageMutable().setCode(c);
};
int main(int argc, char * argv[]) {
piCout << "start ...";
PIHTTPServer server;
server.registerUnhandled([](const MessageConst & msg) { return createMessage(Code::BadRequest, "unhadled", msg); });
server.registerPath("api/v1/status", Method::Get, [](const MessageConst & msg) {
return createMessage(Code::Accepted, "api/v1/status", msg);
});
server.registerPath("api/v1/plugins", Method::Get, [](const MessageConst & msg) {
return createMessage(Code::Accepted, "api/v1/plugins", msg);
});
server.registerPath("api/v1/task-status", Method::Get, [](const MessageConst & msg) {
return createMessage(Code::Accepted, "api/v1/task-status", msg);
});
server.registerPath("api/v1/task/{taskID}/status", Method::Get, [](const MessageConst & msg) {
return createMessage(Code::Accepted, "api/v1/task/{taskID}/status", msg);
});
server.registerPath("api/v1/bort/list", Method::Get, [](const MessageConst & msg) {
return createMessage(Code::Accepted, "api/v1/bort/list", msg);
});
server.registerPath("api/v1/all", Method::Get, [](const MessageConst & msg) {
return createMessage(Code::Accepted, "api/v1/all", msg);
});
server.registerPath("api/v1/all/bort{A}/f", Method::Get, [](const MessageConst & msg) {
return createMessage(Code::Accepted, "api/v1/all/*/f", msg);
});
server.registerPath("api/v1/all2/**", Method::Get, [](const MessageConst & msg) {
return createMessage(Code::Accepted, "api/v1/all2/**", msg);
});
server.listenAll(12345);
// piCout << "start ...";
// PIHTTPServer server;
// server.registerUnhandled([](const MessageConst & msg) { return createMessage(Code::BadRequest, "unhadled", msg); });
// server.registerPath("api/v1/status", Method::Get, [](const MessageConst & msg) {
// return createMessage(Code::Accepted, "api/v1/status", msg);
// });
// server.registerPath("api/v1/plugins", Method::Get, [](const MessageConst & msg) {
// return createMessage(Code::Accepted, "api/v1/plugins", msg);
// });
// server.registerPath("api/v1/task-status", Method::Get, [](const MessageConst & msg) {
// return createMessage(Code::Accepted, "api/v1/task-status", msg);
// });
// server.registerPath("api/v1/task/{taskID}/status", Method::Get, [](const MessageConst & msg) {
// return createMessage(Code::Accepted, "api/v1/task/{taskID}/status", msg);
// });
// server.registerPath("api/v1/bort/list", Method::Get, [](const MessageConst & msg) {
// return createMessage(Code::Accepted, "api/v1/bort/list", msg);
// });
// server.registerPath("api/v1/all", Method::Get, [](const MessageConst & msg) {
// return createMessage(Code::Accepted, "api/v1/all", msg);
// });
// server.registerPath("api/v1/all/bort{A}/f", Method::Get, [](const MessageConst & msg) {
// return createMessage(Code::Accepted, "api/v1/all/*/f", msg);
// });
// server.registerPath("api/v1/all2/**", Method::Get, [](const MessageConst & msg) {
// return createMessage(Code::Accepted, "api/v1/all2/**", msg);
// });
// server.listenAll(12345);
kbd.enableExitCapture('Q');
WAIT_FOR_EXIT
piCout << "exiting ...";
server.stop();
// kbd.enableExitCapture('Q');
// WAIT_FOR_EXIT
// piCout << "exiting ...";
// server.stop();
return 0;
// return 0;
PISystemMonitor mon;
mon.startOnSelf();
PISystemMonitor::totalRAM();
2_s .sleep();
// PISystemMonitor mon;
// mon.startOnSelf();
// PISystemMonitor::totalRAM();
// 2_s .sleep();
return 0;
// return 0;
PIMQTT::Client cl;
cl.setConnectTimeout(2_s);
CONNECTL(&cl, connected, [&cl] {
piCout << "connected";
cl.subscribe("/zigbee2mqtt");
cl.subscribe("/zigbee2mqtt/+");
cl.unsubscribe("/zigbee2mqtt");
cl.publish("/zigbee2mqtt/abc", "hello from PIP"_a.toAscii());
// cl.subscribe("api/v1/plugins");
// cl.subscribe("api/v1/task-status");
// cl.subscribe("api/v1/*/{taskID}/status");
// cl.subscribe("api/v1/bort/list");
// cl.subscribe("api/v1/all");
cl.subscribe("api/v1/all/bort{A}/f", [](const PIMQTT::MessageConst & msg) {
piCout << "1" << msg.topicList() << msg.pathArguments() << msg.body().size();
});
cl.subscribe("api/v1/all/task{T}/f", [](const PIMQTT::MessageConst & msg) {
piCout << "2" << msg.topicList() << msg.pathArguments() << msg.body().size();
});
cl.subscribe("api/v1/all/*/f", [](const PIMQTT::MessageConst & msg) {
piCout << "3" << msg.topicList() << msg.pathArguments() << msg.body().size();
});
cl.subscribe("api/v1/all2/**", [](const PIMQTT::MessageConst & msg) {
piCout << "4" << msg.topicList() << msg.pathArguments() << msg.body().size();
});
// cl.subscribe("/zigbee2mqtt");
// cl.subscribe("/zigbee2mqtt/+/status/");
// cl.subscribe("/zigbee2mqtt/*/status/");
// cl.subscribe("test/#");
// cl.subscribe("#");
// cl.unsubscribe("/zigbee2mqtt");
// cl.unsubscribe("api/v1/all/bort{A}/f");
// cl.unsubscribe("api/v1/all/*/f");
// cl.publish("/zigbee2mqtt/abc", "hello from PIP"_a.toAscii());
});
CONNECTL(&cl, disconnected, [&cl](PIMQTT::Error code) {
piCout << "disconnected code" << (int)code;
cl.connect("localhost", "PIP");
});
CONNECTL(&cl, received, [](const PIMQTT::MessageConst & message) {
piCout << "received" << message.topic() << message.pathArguments() << message.payload().size();
CONNECTL(&cl, receivedUnhandled, [](const PIMQTT::MessageConst & message) {
piCout << "receivedUnhandled" << message.topic() << message.pathArguments() << message.payload().size();
});
cl.connect("localhost", "PIP");