Configure board deployment and backend proxy
This commit is contained in:
@@ -0,0 +1,91 @@
|
||||
import { createServer } from 'node:http';
|
||||
import { pathToFileURL } from 'node:url';
|
||||
import { WebSocketServer } from 'ws';
|
||||
|
||||
function isFocusEvent(value) {
|
||||
return (
|
||||
typeof value === 'object' &&
|
||||
value !== null &&
|
||||
value.type === 'FOCUS_NAME' &&
|
||||
typeof value.cloudId === 'string' &&
|
||||
typeof value.name === 'string' &&
|
||||
typeof value.messageId === 'string' &&
|
||||
typeof value.sentAt === 'number' &&
|
||||
(value.targetIndex === undefined ||
|
||||
(typeof value.targetIndex === 'number' &&
|
||||
Number.isInteger(value.targetIndex) &&
|
||||
value.targetIndex >= 0))
|
||||
);
|
||||
}
|
||||
|
||||
export function createRealtimeServer(port = Number(process.env.REALTIME_PORT || 8787)) {
|
||||
const server = createServer((request, response) => {
|
||||
if (request.url === '/healthz') {
|
||||
response.writeHead(200, { 'content-type': 'application/json' });
|
||||
response.end(JSON.stringify({ status: 'ok' }));
|
||||
return;
|
||||
}
|
||||
|
||||
response.writeHead(404, { 'content-type': 'text/plain' });
|
||||
response.end('Not found');
|
||||
});
|
||||
const realtime = new WebSocketServer({
|
||||
server,
|
||||
maxPayload: 16 * 1024,
|
||||
});
|
||||
const heartbeat = setInterval(() => {
|
||||
for (const socket of realtime.clients) {
|
||||
if (socket.isAlive === false) {
|
||||
socket.terminate();
|
||||
continue;
|
||||
}
|
||||
|
||||
socket.isAlive = false;
|
||||
socket.ping();
|
||||
}
|
||||
}, 30_000);
|
||||
|
||||
heartbeat.unref();
|
||||
|
||||
realtime.on('connection', (socket) => {
|
||||
socket.isAlive = true;
|
||||
socket.on('pong', () => {
|
||||
socket.isAlive = true;
|
||||
});
|
||||
|
||||
socket.on('message', (data) => {
|
||||
let value;
|
||||
|
||||
try {
|
||||
value = JSON.parse(data.toString());
|
||||
} catch {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!isFocusEvent(value)) {
|
||||
return;
|
||||
}
|
||||
|
||||
const message = JSON.stringify(value);
|
||||
|
||||
for (const client of realtime.clients) {
|
||||
if (client !== socket && client.readyState === client.OPEN) {
|
||||
client.send(message);
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
realtime.on('close', () => {
|
||||
clearInterval(heartbeat);
|
||||
});
|
||||
|
||||
return server;
|
||||
}
|
||||
|
||||
if (import.meta.url === pathToFileURL(process.argv[1] || '').href) {
|
||||
const port = Number(process.env.REALTIME_PORT || 8787);
|
||||
createRealtimeServer(port).listen(port, () => {
|
||||
console.log(`Realtime WebSocket server listening on port ${port}`);
|
||||
});
|
||||
}
|
||||
Reference in New Issue
Block a user