From e6e1b113695dee3f2ae9a23e27b22522864d7858 Mon Sep 17 00:00:00 2001 From: Sem van der Hoeven Date: Tue, 30 May 2023 22:02:02 +0200 Subject: [PATCH] add SSE for receiving failsafe status --- api/index.js | 116 +++++++++++------- api/views/index.ejs | 6 + .../api_communication/api_listener.py | 2 + 3 files changed, 81 insertions(+), 43 deletions(-) diff --git a/api/index.js b/api/index.js index 8a7df15f..c2122385 100644 --- a/api/index.js +++ b/api/index.js @@ -2,50 +2,79 @@ var express = require("express"); var app = express(); const WebSocket = require("ws"); +//# TODO SSE https://www.digitalocean.com/community/tutorials/nodejs-server-sent-events-build-realtime-app + var last_status = {}; var last_image; var received_picture = false; var received_error = false; +let sse_clients = []; + app.use(express.static("public")); app.use(express.json()); var ws; var api_connected = false; -var connect_to_api = function () { - console.log("Connecting to API") - ws = new WebSocket("ws://10.100.0.40:9001/"); +function send_events_to_clients(data) { + sse_clients.forEach(client => client.response.write(`data: ${JSON.stringify(data)}\n\n`)); +} - ws.on("open", function open() { - console.log("connected with websockets to API!"); - api_connected = true; - }); - - ws.on("message", function message(message) { - try { - var msg = JSON.parse(message); - if (msg.type == "STATUS") { - last_status = msg.data; - } else if (msg.type == "IMAGE") { - console.log("got picture"); - // console.log(msg.image); - last_image = msg.image; - received_picture = true; - } - } catch (error) { - console.log("could not parse as json") +function handle_sse_client(request, response, next) { + const headers = { + "Content-Type": "text/event-stream", + 'Connection': "keep-alive", + "Cache-Control": "no-cache", + }; + // response.writeHead(200, headers); + // response.write("yeet\n\n"); + const clientID = Date.now(); + const newClient = { + id: clientID, + response + }; - } - }); - - ws.on("error", function error(err) { - console.log("there was an error") - console.error("error: " + err); - received_error = true; + sse_clients.push(newClient); + + request.on("close", () => { + console.log(`${clientID} Connection closed`); + sse_clients = sse_clients.filter(client => client.id !== clientID); }); } +var connect_to_api = function () { + console.log("Connecting to API"); + ws = new WebSocket("ws://10.100.0.40:9001/"); + + ws.on("open", function open() { + console.log("connected with websockets to API!"); + api_connected = true; + }); + + ws.on("message", function message(message) { + try { + var msg = JSON.parse(message); + if (msg.type == "STATUS") { + last_status = msg.data; + send_events_to_clients(message); + } else if (msg.type == "IMAGE") { + console.log("got picture"); + // console.log(msg.image); + last_image = msg.image; + received_picture = true; + } + } catch (error) { + console.log("could not parse as json"); + } + }); + + ws.on("error", function error(err) { + console.log("there was an error"); + console.error("error: " + err); + received_error = true; + }); +}; // set the view engine to ejs app.set("view engine", "ejs"); @@ -61,12 +90,14 @@ app.get("/status", function (req, res) { res.status(200).json(last_status); }); -app.get("/image", function (req, res) { +app.get("/events", handle_sse_client); + +app.get("/image", function (req, res) { console.log("got picture request"); var request = JSON.stringify({ - command: 5 + command: 5, }); - console.log("sending picture request") + console.log("sending picture request"); ws.send(request); res.status(200).send(last_image); }); @@ -78,23 +109,22 @@ app.post("/move", function (req, res) { up_down: req.body.up_down, left_right: req.body.left_right, forward_backward: req.body.forward_backward, - yaw: req.body.turn_left_right + yaw: req.body.turn_left_right, }); ws.send(request); }); app.get("/connect", function (req, res) { - console.log("got connect request"); - connect_to_api(); - setTimeout(function () { - if (api_connected) { - res.status(200).json({ connected: true }); - } else { - received_error = false; - res.status(400).json({ connected: false }); - } - }, 1000); - + console.log("got connect request"); + connect_to_api(); + setTimeout(function () { + if (api_connected) { + res.status(200).json({ connected: true }); + } else { + received_error = false; + res.status(400).json({ connected: false }); + } + }, 1000); }); app.listen(8080); diff --git a/api/views/index.ejs b/api/views/index.ejs index 8849a74d..18e7a1af 100644 --- a/api/views/index.ejs +++ b/api/views/index.ejs @@ -60,6 +60,12 @@