148 {
149 const express::Router& jsonRouter = express::middleware::JsonMiddleware();
150
151
152
153
154
155 jsonRouter.use("/api/mqtt", [] MIDDLEWARE(req, res, next) {
156 res->set({{"Access-Control-Allow-Origin", "*"},
157 {"Access-Control-Allow-Headers", "Content-Type"},
158 {"Access-Control-Allow-Methods", "GET, OPTIONS, POST"},
159 {"Access-Control-Allow-Private-Network", "true"}});
160 next();
161 });
162
163 jsonRouter.post("/api/mqtt/disconnect", [] APPLICATION(req, res) {
164 VLOG(1) << "POST /disconnect";
165
166 req->getAttribute<nlohmann::json>(
167 [&res](nlohmann::json&
json) {
168 std::string jsonString =
json.dump(4);
169
170 VLOG(1) << jsonString;
171
172 std::string clientId =
json[
"clientId"].get<std::string>();
174
175 if (
mqtt !=
nullptr) {
176 mqtt->getMqttContext()->getSocketConnection()->close();
177 res->send(R"({"success": true, "message": "Client disconnected successfully"})"_json.dump());
178 } else {
179 res->status(404).send(R"({"success": false, "error": "Client not found"})"_json.dump());
180 }
181 },
182 [&res](const std::string& key) {
183 VLOG(1) << "Attribute type not found: " << key;
184
185 res->status(400).send("Attribute type not found: " + key);
186 });
187 });
188
189
190
191
192
193 jsonRouter.post("/api/mqtt/unsubscribe", [] APPLICATION(req, res) {
194 VLOG(1) << "POST /unsubscribe";
195
196 req->getAttribute<nlohmann::json>(
197 [&res](nlohmann::json&
json) {
198 std::string jsonString =
json.dump(4);
199
200 VLOG(1) << jsonString;
201
202 std::string clientId =
json[
"clientId"].get<std::string>();
203 std::string topic =
json[
"topic"].get<std::string>();
204
206
207 if (
mqtt !=
nullptr) {
208 mqtt->unsubscribe(topic);
209 res->send(R"({"success": true, "message": "Client unsubscribed successfully"})"_json.dump());
210 } else {
211 res->status(404).send(R"({"success": false, "error": "Client not found"})"_json.dump());
212 }
213 },
214 [&res](const std::string& key) {
215 VLOG(1) << "Attribute type not found: " << key;
216
217 res->status(400).send("Attribute type not found: " + key);
218 });
219 });
220
221
222
223
224
225 jsonRouter.post("/api/mqtt/release", [broker] APPLICATION(req, res) {
226 VLOG(1) << "POST /release";
227
228 req->getAttribute<nlohmann::json>(
229 [&res, broker](nlohmann::json&
json) {
230 std::string jsonString =
json.dump(4);
231
232 VLOG(1) << jsonString;
233
234 std::string topic =
json[
"topic"].get<std::string>();
235
236 broker->publish("", topic, "", 0, true);
238
239 res->send(R"({"success": true, "message": "Retained message released successfully"})"_json.dump());
240 },
241 [&res](const std::string& key) {
242 VLOG(1) << "Attribute type not found: " << key;
243
244 res->status(400).send("Attribute type not found: " + key);
245 });
246 });
247
248
249
250
251
252 jsonRouter.post("/api/mqtt/subscribe", [] APPLICATION(req, res) {
253 VLOG(1) << "POST /subscribe";
254
255 req->getAttribute<nlohmann::json>(
256 [&res](nlohmann::json&
json) {
257 std::string jsonString =
json.dump(4);
258
259 VLOG(1) << jsonString;
260
261 std::string clientId =
json[
"clientId"].get<std::string>();
262 std::string topic =
json[
"topic"].get<std::string>();
263 uint8_t qoS =
json[
"qos"].get<uint8_t>();
264
266
267 if (
mqtt !=
nullptr) {
268 mqtt->subscribe(topic, qoS);
269
270 res->send(R"({"success": true, "message": "Client subscribed successfully"})"_json.dump());
271 } else {
272 res->status(404).send(R"({"success": false, "error": "Client not found"})"_json.dump());
273 }
274 },
275 [&res](const std::string& key) {
276 VLOG(1) << "Attribute type not found: " << key;
277
278 res->status(400).send("Attribute type not found: " + key);
279 });
280 });
281 const express::Router router;
282
283 router.use(jsonRouter);
284
285 router.get("/api/mqtt/events", [broker] APPLICATION(req, res) {
286 if (web::http::ciContains(req->get("Accept"), "text/event-stream")) {
287 res->set({{"Content-Type", "text/event-stream"},
288 {"Cache-Control", "no-cache"},
289 {"Connection", "keep-alive"},
290 {"Access-Control-Allow-Origin", "*"}});
291
292 res->sendHeader();
293
295 } else {
296 res->redirect("/clients");
297 }
298 });
299
300 router.get("/ws", [] APPLICATION(req, res) {
301 if (req->headers.contains("upgrade")) {
303 } else {
304 res->redirect("/clients");
305 }
306 });
307
308 router.get("/mqtt", [] APPLICATION(req, res) {
309 if (req->headers.contains("upgrade")) {
311 } else {
312 res->redirect("/clients");
313 }
314 });
315
316 router.get("/", [] APPLICATION(req, res) {
317 if (req->headers.contains("upgrade")) {
319 } else {
320 res->redirect("/clients");
321 }
322 });
323
324 router.get("/sse", [broker] APPLICATION(req, res) {
325 if (web::http::ciContains(req->get("Accept"), "text/event-stream")) {
326 res->set("Content-Type", "text/event-stream")
327 .set("Cache-Control", "no-cache")
328 .set("Connection", "keep-alive");
329 res->sendHeader();
330
332 } else {
333 res->redirect("/clients");
334 }
335 });
336
337 router.get("/clients", [] APPLICATION(req, res) {
338 res->redirect("/clients/index.html");
339 });
340
341 router.use("/clients", express::middleware::StaticMiddleware(webRoot));
342
343 router.get("*", [] APPLICATION(req, res) {
344 res->redirect("/clients/index.html");
345 });
346
347 return router;
348}
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(const std::shared_ptr< express::Request > &req, const std::shared_ptr< express::Response > &res)