add SSE for receiving failsafe status
This commit is contained in:
112
api/index.js
112
api/index.js
@@ -2,50 +2,79 @@ var express = require("express");
|
|||||||
var app = express();
|
var app = express();
|
||||||
const WebSocket = require("ws");
|
const WebSocket = require("ws");
|
||||||
|
|
||||||
|
//# TODO SSE https://www.digitalocean.com/community/tutorials/nodejs-server-sent-events-build-realtime-app
|
||||||
|
|
||||||
var last_status = {};
|
var last_status = {};
|
||||||
var last_image;
|
var last_image;
|
||||||
var received_picture = false;
|
var received_picture = false;
|
||||||
var received_error = false;
|
var received_error = false;
|
||||||
|
|
||||||
|
let sse_clients = [];
|
||||||
|
|
||||||
app.use(express.static("public"));
|
app.use(express.static("public"));
|
||||||
app.use(express.json());
|
app.use(express.json());
|
||||||
|
|
||||||
var ws;
|
var ws;
|
||||||
var api_connected = false;
|
var api_connected = false;
|
||||||
|
|
||||||
var connect_to_api = function () {
|
function send_events_to_clients(data) {
|
||||||
console.log("Connecting to API")
|
sse_clients.forEach(client => client.response.write(`data: ${JSON.stringify(data)}\n\n`));
|
||||||
ws = new WebSocket("ws://10.100.0.40:9001/");
|
}
|
||||||
|
|
||||||
ws.on("open", function open() {
|
function handle_sse_client(request, response, next) {
|
||||||
console.log("connected with websockets to API!");
|
const headers = {
|
||||||
api_connected = true;
|
"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("message", function message(message) {
|
sse_clients.push(newClient);
|
||||||
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")
|
|
||||||
|
|
||||||
}
|
request.on("close", () => {
|
||||||
});
|
console.log(`${clientID} Connection closed`);
|
||||||
|
sse_clients = sse_clients.filter(client => client.id !== clientID);
|
||||||
ws.on("error", function error(err) {
|
|
||||||
console.log("there was an error")
|
|
||||||
console.error("error: " + err);
|
|
||||||
received_error = true;
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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
|
// set the view engine to ejs
|
||||||
app.set("view engine", "ejs");
|
app.set("view engine", "ejs");
|
||||||
@@ -61,12 +90,14 @@ app.get("/status", function (req, res) {
|
|||||||
res.status(200).json(last_status);
|
res.status(200).json(last_status);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
app.get("/events", handle_sse_client);
|
||||||
|
|
||||||
app.get("/image", function (req, res) {
|
app.get("/image", function (req, res) {
|
||||||
console.log("got picture request");
|
console.log("got picture request");
|
||||||
var request = JSON.stringify({
|
var request = JSON.stringify({
|
||||||
command: 5
|
command: 5,
|
||||||
});
|
});
|
||||||
console.log("sending picture request")
|
console.log("sending picture request");
|
||||||
ws.send(request);
|
ws.send(request);
|
||||||
res.status(200).send(last_image);
|
res.status(200).send(last_image);
|
||||||
});
|
});
|
||||||
@@ -78,23 +109,22 @@ app.post("/move", function (req, res) {
|
|||||||
up_down: req.body.up_down,
|
up_down: req.body.up_down,
|
||||||
left_right: req.body.left_right,
|
left_right: req.body.left_right,
|
||||||
forward_backward: req.body.forward_backward,
|
forward_backward: req.body.forward_backward,
|
||||||
yaw: req.body.turn_left_right
|
yaw: req.body.turn_left_right,
|
||||||
});
|
});
|
||||||
ws.send(request);
|
ws.send(request);
|
||||||
});
|
});
|
||||||
|
|
||||||
app.get("/connect", function (req, res) {
|
app.get("/connect", function (req, res) {
|
||||||
console.log("got connect request");
|
console.log("got connect request");
|
||||||
connect_to_api();
|
connect_to_api();
|
||||||
setTimeout(function () {
|
setTimeout(function () {
|
||||||
if (api_connected) {
|
if (api_connected) {
|
||||||
res.status(200).json({ connected: true });
|
res.status(200).json({ connected: true });
|
||||||
} else {
|
} else {
|
||||||
received_error = false;
|
received_error = false;
|
||||||
res.status(400).json({ connected: false });
|
res.status(400).json({ connected: false });
|
||||||
}
|
}
|
||||||
}, 1000);
|
}, 1000);
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
app.listen(8080);
|
app.listen(8080);
|
||||||
|
|||||||
@@ -60,6 +60,12 @@
|
|||||||
<script>
|
<script>
|
||||||
var update_status = setInterval(update_status, 1000);
|
var update_status = setInterval(update_status, 1000);
|
||||||
assign_button_callbacks();
|
assign_button_callbacks();
|
||||||
|
const events = new EventSource("/events");
|
||||||
|
events.onmessage = (event) => {
|
||||||
|
const parsedData = JSON.parse(event.data);
|
||||||
|
console.log("RECEIVED EVENT");
|
||||||
|
console.log(parsedData);
|
||||||
|
}
|
||||||
|
|
||||||
function assign_button_callbacks() {
|
function assign_button_callbacks() {
|
||||||
var buttons = document.getElementsByClassName("movebutton");
|
var buttons = document.getElementsByClassName("movebutton");
|
||||||
|
|||||||
@@ -16,6 +16,8 @@ import base64
|
|||||||
# communication: client always sends commands that have a command id.
|
# communication: client always sends commands that have a command id.
|
||||||
# server always sends messages back that have a message type
|
# server always sends messages back that have a message type
|
||||||
|
|
||||||
|
# TODO send video https://github.com/Jatin1o1/Python-Javascript-Websocket-Video-Streaming-/tree/main
|
||||||
|
|
||||||
|
|
||||||
class RequestCommand(Enum):
|
class RequestCommand(Enum):
|
||||||
GET_COMMANDS_TYPES = -1 # to get the available commands and types
|
GET_COMMANDS_TYPES = -1 # to get the available commands and types
|
||||||
|
|||||||
Reference in New Issue
Block a user