167 {
168 const express::Router& jsonRouter = express::middleware::JsonMiddleware();
169
170
171
172
173
174 jsonRouter.use("/api/mqtt", [] MIDDLEWARE(req, res, next) {
175 res->set({{"Access-Control-Allow-Origin", "*"},
176 {"Access-Control-Allow-Headers", "Content-Type"},
177 {"Access-Control-Allow-Methods", "GET, OPTIONS, POST"},
178 {"Access-Control-Allow-Private-Network", "true"}});
179 next();
180 });
181
182 jsonRouter.post(
"/api/mqtt/disconnect", []
APPLICATION(req, res) {
183 VLOG(1) << "POST /disconnect";
184
185 req->getAttribute<nlohmann::json>(
186 [&res](nlohmann::json&
json) {
187 std::string jsonString =
json.dump(4);
188
189 VLOG(1) << jsonString;
190
191 std::string clientId =
json[
"clientId"].get<std::string>();
193
194 if (
mqtt !=
nullptr) {
195 mqtt->getMqttContext()->getSocketConnection()->close();
196 res->send(R"({"success": true, "message": "Client disconnected successfully"})"_json.dump());
197 } else {
198 res->status(404).send(R"({"success": false, "error": "Client not found"})"_json.dump());
199 }
200 },
201 [&res](const std::string& key) {
202 VLOG(1) << "Attribute type not found: " << key;
203
204 res->status(400).send("Attribute type not found: " + key);
205 });
206 });
207
208
209
210
211
212 jsonRouter.post(
"/api/mqtt/unsubscribe", []
APPLICATION(req, res) {
213 VLOG(1) << "POST /unsubscribe";
214
215 req->getAttribute<nlohmann::json>(
216 [&res](nlohmann::json&
json) {
217 std::string jsonString =
json.dump(4);
218
219 VLOG(1) << jsonString;
220
221 std::string clientId =
json[
"clientId"].get<std::string>();
222 std::string topic =
json[
"topic"].get<std::string>();
223
225
226 if (
mqtt !=
nullptr) {
227 mqtt->unsubscribe(topic);
228 res->send(R"({"success": true, "message": "Client unsubscribed successfully"})"_json.dump());
229 } else {
230 res->status(404).send(R"({"success": false, "error": "Client not found"})"_json.dump());
231 }
232 },
233 [&res](const std::string& key) {
234 VLOG(1) << "Attribute type not found: " << key;
235
236 res->status(400).send("Attribute type not found: " + key);
237 });
238 });
239
240
241
242
243
244 jsonRouter.post(
"/api/mqtt/release", [broker]
APPLICATION(req, res) {
245 VLOG(1) << "POST /release";
246
247 req->getAttribute<nlohmann::json>(
248 [&res, broker](nlohmann::json&
json) {
249 std::string jsonString =
json.dump(4);
250
251 VLOG(1) << jsonString;
252
253 std::string topic =
json[
"topic"].get<std::string>();
254
255 broker->publish("", topic, "", 0, true);
257
258 res->send(R"({"success": true, "message": "Retained message released successfully"})"_json.dump());
259 },
260 [&res](const std::string& key) {
261 VLOG(1) << "Attribute type not found: " << key;
262
263 res->status(400).send("Attribute type not found: " + key);
264 });
265 });
266
267
268
269
270
271 jsonRouter.post(
"/api/mqtt/subscribe", []
APPLICATION(req, res) {
272 VLOG(1) << "POST /subscribe";
273
274 req->getAttribute<nlohmann::json>(
275 [&res](nlohmann::json&
json) {
276 std::string jsonString =
json.dump(4);
277
278 VLOG(1) << jsonString;
279
280 std::string clientId =
json[
"clientId"].get<std::string>();
281 std::string topic =
json[
"topic"].get<std::string>();
282 uint8_t qoS =
json[
"qos"].get<uint8_t>();
283
285
286 if (
mqtt !=
nullptr) {
287 mqtt->subscribe(topic, qoS);
288
289 res->send(R"({"success": true, "message": "Client subscribed successfully"})"_json.dump());
290 } else {
291 res->status(404).send(R"({"success": false, "error": "Client not found"})"_json.dump());
292 }
293 },
294 [&res](const std::string& key) {
295 VLOG(1) << "Attribute type not found: " << key;
296
297 res->status(400).send("Attribute type not found: " + key);
298 });
299 });
300 const express::Router router;
301
302 router.use(jsonRouter);
303
304 router.get(
"/api/mqtt/events", [broker]
APPLICATION(req, res) {
305 if (web::http::ciContains(req->get("Accept"), "text/event-stream")) {
306 res->set({{"Content-Type", "text/event-stream"},
307 {"Cache-Control", "no-cache"},
308 {"Connection", "keep-alive"},
309 {"Access-Control-Allow-Origin", "*"}});
310
311 res->sendHeader();
312
314 } else {
315 res->redirect("/clients");
316 }
317 });
318
319 router.setStrictRouting();
321 res->redirect("/clients/index.html");
322 });
323
324 router.get("/clients", express::middleware::StaticMiddleware(utils::Config::getStringOptionValue("--html-dir")));
325
327 if (req->headers.contains("upgrade")) {
328 upgrade(req, res);
329 } else {
330 res->redirect("/clients");
331 }
332 });
333
335 if (req->headers.contains("upgrade")) {
336 upgrade(req, res);
337 } else {
338 res->redirect("/clients");
339 }
340 });
341
343 if (req->headers.contains("upgrade")) {
344 upgrade(req, res);
345 } else {
346 res->redirect("/clients");
347 }
348 });
349
350 router.get(
"/sse", [broker]
APPLICATION(req, res) {
351 if (web::http::ciContains(req->get("Accept"), "text/event-stream")) {
352 res->set("Content-Type", "text/event-stream")
353 .set("Cache-Control", "no-cache")
354 .set("Connection", "keep-alive");
355 res->sendHeader();
356
358 } else {
359 res->redirect("/clients");
360 }
361 });
362
363 return router;
364}
void publishMessage(const std::string &topic, const std::string &message, uint8_t qoS, bool retain)
void addEventReceiver(const std::shared_ptr< express::Response > &response, const std::string &lastEventId, const std::shared_ptr< iot::mqtt::server::broker::Broker > &broker)
static MqttModel & instance()
Mqtt * getMqtt(const std::string &clientId) const
static void upgrade APPLICATION(req, res)