fix: render live V2X vehicles in Cesium preview
This commit is contained in:
@@ -34,11 +34,15 @@ function parseArgs(argv) {
|
||||
return values;
|
||||
}
|
||||
|
||||
function createV2xPreviewServer({ root, upstream }) {
|
||||
function createV2xPreviewServer({ root, upstream, wsUpstream }) {
|
||||
const staticRoot = path.resolve(root);
|
||||
const upstreamUrl = new URL(upstream);
|
||||
// Deployments front the API and the WebSocket with different prefixes (e.g.
|
||||
// /dashboardApi and /dashboardWebsocket), so the two targets are separate.
|
||||
const wsUpstreamUrl = wsUpstream ? new URL(wsUpstream) : upstreamUrl;
|
||||
if (!fs.statSync(staticRoot).isDirectory()) throw new Error(`Preview root is not a directory: ${staticRoot}`);
|
||||
if (!/^https?:$/.test(upstreamUrl.protocol)) throw new Error("V2X upstream must use http or https");
|
||||
if (!/^https?:$/.test(wsUpstreamUrl.protocol)) throw new Error("V2X websocket upstream must use http or https");
|
||||
|
||||
const server = http.createServer((request, response) => {
|
||||
if (isProxyPath(request.url)) {
|
||||
@@ -53,7 +57,7 @@ function createV2xPreviewServer({ root, upstream }) {
|
||||
socket.destroy();
|
||||
return;
|
||||
}
|
||||
proxyWebSocket(request, socket, head, upstreamUrl);
|
||||
proxyWebSocket(request, socket, head, wsUpstreamUrl);
|
||||
});
|
||||
return server;
|
||||
}
|
||||
@@ -64,10 +68,15 @@ function isProxyPath(url) {
|
||||
pathname === "/websocket" || pathname.startsWith("/websocket/");
|
||||
}
|
||||
|
||||
function upstreamPath(url) {
|
||||
// The browser calls /api/... and /websocket/...; the local prefix is dropped and
|
||||
// whatever base path the upstream URL carries is prepended, so an upstream of
|
||||
// http://host:7862/dashboardApi maps /api/facilities/... onto
|
||||
// /dashboardApi/facilities/... instead of the bare backend path.
|
||||
function upstreamPath(url, basePath) {
|
||||
const parsed = new URL(url, "http://preview.local");
|
||||
const pathname = parsed.pathname.replace(/^\/(api|websocket)(?=\/|$)/, "") || "/";
|
||||
return `${pathname}${parsed.search}`;
|
||||
const base = String(basePath || "").replace(/\/+$/, "");
|
||||
return `${base}${pathname}${parsed.search}`;
|
||||
}
|
||||
|
||||
function upstreamRequestOptions(request, upstreamUrl) {
|
||||
@@ -76,7 +85,7 @@ function upstreamRequestOptions(request, upstreamUrl) {
|
||||
hostname: upstreamUrl.hostname,
|
||||
port: upstreamUrl.port || undefined,
|
||||
method: request.method,
|
||||
path: upstreamPath(request.url),
|
||||
path: upstreamPath(request.url, upstreamUrl.pathname),
|
||||
headers: { ...request.headers, host: upstreamUrl.host },
|
||||
};
|
||||
}
|
||||
@@ -155,12 +164,13 @@ if (require.main === module) {
|
||||
const args = parseArgs(process.argv.slice(2));
|
||||
const root = args.root || process.cwd();
|
||||
const upstream = args.upstream || process.env.V2X_UPSTREAM;
|
||||
const wsUpstream = args.wsUpstream || process.env.V2X_WS_UPSTREAM;
|
||||
const port = Number(args.port || process.env.PORT || 7862);
|
||||
const host = args.host || process.env.HOST || "0.0.0.0";
|
||||
if (!upstream) throw new Error("Set V2X_UPSTREAM or pass --upstream http://host:port");
|
||||
if (!Number.isInteger(port) || port < 1 || port > 65535) throw new Error("Port must be an integer between 1 and 65535");
|
||||
const server = createV2xPreviewServer({ root, upstream });
|
||||
server.listen(port, host, () => console.log(`V2X preview server: http://${host}:${port} -> ${upstream}`));
|
||||
const server = createV2xPreviewServer({ root, upstream, wsUpstream });
|
||||
server.listen(port, host, () => console.log(`V2X preview server: http://${host}:${port} -> ${upstream} (ws -> ${wsUpstream || upstream})`));
|
||||
}
|
||||
|
||||
module.exports = { createV2xPreviewServer, isProxyPath, upstreamPath };
|
||||
|
||||
Reference in New Issue
Block a user