Files
fx_cast/app/src/daemon.ts
2022-04-25 10:17:59 +01:00

56 lines
1.6 KiB
TypeScript

"use strict";
import { spawn } from "child_process";
import { Readable } from "stream";
import WebSocket from "ws";
import { DecodeTransform, EncodeTransform } from "./transforms";
export function init(port: number) {
process.stdout.write("Starting WebSocket server... ");
const wss = new WebSocket.Server({ port }, () => {
// eslint-disable-next-line no-console
console.log("Done!");
});
wss.on("error", err => {
// eslint-disable-next-line no-console
console.log("Failed!");
console.error(err);
});
wss.on("connection", socket => {
// Stream for incoming WebSocket messages
const messageStream = new Readable({ objectMode: true });
// eslint-disable-next-line @typescript-eslint/no-empty-function
messageStream._read = () => {};
socket.on("message", (message: string) => {
messageStream.push(JSON.parse(message));
});
/**
* Daemon and bridge are the same binary, so spawn a new
* version of self in bridge mode.
*/
const bridge = spawn(process.execPath, [process.argv[1]]);
// socket -> bridge.stdin
messageStream.pipe(new EncodeTransform()).pipe(bridge.stdin);
// bridge.stdout -> socket
bridge.stdout.pipe(new DecodeTransform()).on("data", data => {
// Socket can be CLOSING here
if (socket.readyState === WebSocket.OPEN) {
socket.send(JSON.stringify(data));
}
});
// Handle termination
socket.on("close", () => bridge.kill());
bridge.on("exit", () => socket.close());
});
}