Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat!: migrate to websockets #773

Draft
wants to merge 3 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions .idea/prettier.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 4 additions & 3 deletions backend-mock/apps.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
const express = require("express");
const router = express.Router();
const util = require("./sse/util");
const index = require("./index");

router.post("/install/:id", (req, res) => {
console.info("call to /api/apps/install for app", req.params.id);
// send information that btc-pay is currently installing
util.sendSSE("install", {
util.sendData(index.ws, "install", {
id: "rtl",
mode: "on",
result: "running",
Expand Down Expand Up @@ -44,7 +45,7 @@ const installApp = () => {
console.info("call to installApp");

// inform Frontend that app finished installing
util.sendSSE("install", {
util.sendData(index.ws, "install", {
id: "rtl",
mode: "on",
result: "win",
Expand All @@ -53,7 +54,7 @@ const installApp = () => {
details: "OK",
});

util.sendSSE("installed_app_status", [
util.sendData(index.ws, "installed_app_status", [
{ id: "lnbits", installed: false, status: "offline", error: "" },
{ id: "thunderhub", installed: false, status: "offline", error: "" },
{ id: "btcpayserver", installed: false, status: "offline", error: "" },
Expand Down
73 changes: 39 additions & 34 deletions backend-mock/index.js
Original file line number Diff line number Diff line change
@@ -1,21 +1,27 @@
const express = require("express");
const cors = require("cors");
const WebSocket = require("ws");
const btcInfo = require("./sse/btc_info");
const lnInfo = require("./sse/ln_info");
const installedAppStatus = require("./sse/installed_app_status");
const systemInfo = require("./sse/system_info");
const hardwareInfo = require("./sse/hardware_info");
const walletBalance = require("./sse/wallet_balance");
const systemStartupInfo = require("./sse/system_startup_info");
const util = require("./sse/util");
const setup = require("./setup");
const system = require("./system");
const apps = require("./apps");
const lightning = require("./lightning");
const { createServer } = require("node:http");

require("dotenv").config();

const app = express();
const server = createServer(app);

const wss = new WebSocket.Server({ server, path: "/ws" });
let ws = null;

app.use(
cors({ credentials: true, origin: "http://localhost:3000" }),
express.json(),
Expand All @@ -31,49 +37,48 @@ app.use("/api/lightning", lightning);

const PORT = 8000;

app.listen(PORT, () => {
server.listen(PORT, () => {
console.info(`Server listening on http://localhost:${PORT}`);
console.info(`WebSocket server is running on ws://localhost:${PORT}/ws`);
});

// app.use('/', express.static('../build'));

/**
* Main SSE Handler
* Main WebSocket Handler
*/
const eventsHandler = (request, response) => {
console.info("call to /api/sse/subscribe");
const headers = {
"Content-Type": "text/event-stream",
Connection: "keep-alive",
"Cache-Control": "no-cache",
};
response.writeHead(200, headers);

const data = `data: null\n\n`;
wss.on("connection", (ws) => {
this.ws = ws;
console.info("WebSocket connection established on /ws");

response.write(data);
// Handle incoming messages
ws.on("message", (message) => {
console.info(`Received message: ${message}`);
});

const id = util.currClientId++;
// Handle errors
ws.on("error", (error) => {
console.error("Error occurred:", error);
});

util.clients.push({
id,
response,
// Handle disconnections
ws.on("close", () => {
console.info("Client disconnected");
});

systemStartupInfo.systemStartupInfo();
systemInfo.systemInfo();
hardwareInfo.hardwareInfo();
btcInfo.btcInfo();
lnInfo.lnInfo();
installedAppStatus.appStatus();
walletBalance.walletBalance();
// Send data from SSE handlers to the client
const sendData = () => {
console.info("Sending data to the client");
systemStartupInfo.systemStartupInfo(ws);
systemInfo.systemInfo(ws);
hardwareInfo.hardwareInfo(ws);
btcInfo.btcInfo(ws);
lnInfo.lnInfo(ws);
installedAppStatus.appStatus(ws);
walletBalance.walletBalance(ws);
};

request.on("close", () => {
// do nothing
});
};
// Send initial data to the client
sendData();
});

/**
* SSE Handler call
*/
app.get("/api/sse/subscribe", eventsHandler);
module.exports = { ws };
5 changes: 3 additions & 2 deletions backend-mock/lightning.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ const express = require("express");
const router = express.Router();
const transactions = require("./transactions");
const util = require("./sse/util");
const index = require("./index");

let WALLET_LOCKED = true;

Expand Down Expand Up @@ -235,15 +236,15 @@ router.post("/unlock-wallet", (req, res) => {
if (req.body.password === "password") {
WALLET_LOCKED = false;

util.sendSSE("system_startup_info", {
util.sendData(index.ws, "system_startup_info", {
bitcoin: "done",
bitcoin_msg: "",
lightning: "bootstrapping_after_unlock",
lightning_msg: "",
});

setTimeout(() => {
util.sendSSE("system_startup_info", {
util.sendData(index.ws, "system_startup_info", {
bitcoin: "done",
bitcoin_msg: "",
lightning: "done",
Expand Down
24 changes: 23 additions & 1 deletion backend-mock/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion backend-mock/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
"cors": "^2.8.5",
"dotenv": "^16.3.1",
"express": "^4.18.2",
"jsonwebtoken": "^9.0.1"
"jsonwebtoken": "^9.0.1",
"ws": "^8.18.0"
}
}
4 changes: 2 additions & 2 deletions backend-mock/sse/btc_info.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
const util = require("./util");

const btcInfo = () => {
const btcInfo = (ws) => {
console.info("sending btc_info");

util.sendSSE("btc_info", {
util.sendData(ws, "btc_info", {
blocks: 25,
headers: 25,
verification_progress: 0.9999983702720613,
Expand Down
4 changes: 2 additions & 2 deletions backend-mock/sse/hardware_info.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
const util = require("./util");

const hardwareInfo = () => {
const hardwareInfo = (ws) => {
console.info("sending hardware_info");

util.sendSSE("hardware_info", {
util.sendData(ws, "hardware_info", {
cpu_overall_percent: 1.57,
cpu_per_cpu_percent: [1.64, 1.54, 1.54],
vram_total_bytes: 3844000000,
Expand Down
4 changes: 2 additions & 2 deletions backend-mock/sse/installed_app_status.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
const util = require("./util");

const appStatus = () => {
const appStatus = (ws) => {
console.info("sending installed_app_status");
util.sendSSE("installed_app_status", [
util.sendData(ws, "installed_app_status", [
{
id: "rtl",
installed: false,
Expand Down
4 changes: 2 additions & 2 deletions backend-mock/sse/ln_info.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
const util = require("./util");

const lnInfo = () => {
const lnInfo = (ws) => {
console.info("sending ln_info");

util.sendSSE("ln_info", {
util.sendData(ws, "ln_info", {
implementation: "LND_GRPC",
version: "0.17.3-beta commit=v0.17.3-beta",
commit_hash: "13aa7f99248c7ee63989d3b62e0cbfe86d7b0964",
Expand Down
4 changes: 2 additions & 2 deletions backend-mock/sse/system_info.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
const util = require("./util");

const systemInfo = () => {
const systemInfo = (ws) => {
console.info("sending system_info");

util.sendSSE("system_info", {
util.sendData(ws, "system_info", {
alias: "myBlitz",
color: "#3399ff",
platform: "raspiblitz",
Expand Down
10 changes: 6 additions & 4 deletions backend-mock/sse/system_startup_info.js
Original file line number Diff line number Diff line change
@@ -1,14 +1,16 @@
const util = require("./util");

const systemStartupInfo = () => {
const systemStartupInfo = (ws) => {
console.info("sending system_startup_info");

util.sendSSE("system_startup_info", {
const data = {
bitcoin: "done",
bitcoin_msg: "",
lightning: "locked",
lightning: "",
lightning_msg: "Wallet locked, unlock it to enable full RPC access",
});
};

util.sendData(ws, "system_startup_info", data);
};

module.exports = { systemStartupInfo };
21 changes: 5 additions & 16 deletions backend-mock/sse/util.js
Original file line number Diff line number Diff line change
@@ -1,18 +1,7 @@
/**
* @type {{id: number, response: Response}[]}
*/
let clients = [];
let currClientId = 0;

/**
* @param {string} event the event to send
* @param {any} data data of the event
* @returns void
*/
const sendSSE = (event, data) => {
clients.forEach((client) =>
client.response.write(`event: ${event}\ndata: ${JSON.stringify(data)}\n\n`),
);
const util = {
sendData: (ws, type, data) => {
ws.send(JSON.stringify({ type, data }));
},
};

module.exports = { clients, currClientId, sendSSE };
module.exports = util;
4 changes: 2 additions & 2 deletions backend-mock/sse/wallet_balance.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
const util = require("./util");

const walletBalance = () => {
const walletBalance = (ws) => {
console.info("sending wallet_balance");

util.sendSSE("wallet_balance", {
util.sendData(ws, "wallet_balance", {
onchain_confirmed_balance: 742363,
onchain_total_balance: 742363,
onchain_unconfirmed_balance: 200000000,
Expand Down
11 changes: 5 additions & 6 deletions src/context/app-context.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { SSEContext } from "./sse-context";
import { WebSocketContext } from "@/context/ws-context";
import {
ACCESS_TOKEN,
disableGutter,
Expand Down Expand Up @@ -53,7 +53,7 @@ export const AppContext = createContext<AppContextType>(appContextDefault);

const AppContextProvider: FC<PropsWithChildren> = ({ children }) => {
const { i18n } = useTranslation();
const { evtSource, setEvtSource } = useContext(SSEContext);
const { websocket } = useContext(WebSocketContext);

const [unit, setUnit] = useState<Unit>(Unit.SAT);
const [isLoggedIn, setIsLoggedIn] = useState(false);
Expand All @@ -69,16 +69,15 @@ const AppContextProvider: FC<PropsWithChildren> = ({ children }) => {
localStorage.removeItem(ACCESS_TOKEN);

// close EventSource on logout
if (evtSource) {
evtSource.close();
setEvtSource(null);
if (websocket) {
websocket.close();
}
setIsLoggedIn(false);
disableGutter();
setWindowAlias(null);
toast.dismiss();
navigate("/");
}, [evtSource, setEvtSource, navigate]);
}, [websocket, navigate]);

useEffect(() => {
const settings = retrieveSettings();
Expand Down
Loading