import { globalLogger } from "@config/logger";
import { ObjectId } from "mongodb";
import { randomUUID } from "node:crypto";
import { setupPhysicsHandlers } from "./handlers/physics";
import { WebSocketClient } from "./websocket-client";
/**
* Handle new WebSocket connections
* @param {WebSocket} ws - WebSocket instance
* @param {IncomingMessage} request - HTTP request
*/
export function handleWebSocketConnection(ws, request) {
const connectionId = randomUUID();
const logger = globalLogger.child({ connectionId, transport: "websocket" });
// Parse query parameters
const url = new URL(request.url || "", "ws://localhost");
const userId = url.searchParams.get("userId");
const investigationId = url.searchParams.get("investigationId");
const userName = url.searchParams.get("userName");
// Validate userId
if (!userId || !ObjectId.isValid(userId)) {
logger.warn({ userId }, "Invalid userId");
ws.send(JSON.stringify({ type: "error", data: { message: "Invalid userId parameter" } }));
ws.close(1008, "Invalid userId");
return;
}
// Create client
const client = new WebSocketClient(ws, connectionId, userId, investigationId, logger);
// Use dev-stage physics engine when connecting via api.dev-stage.k12.aaic.dev; otherwise default env host
const requestHost = request.headers.host ?? "";
const physicsEngineHost = requestHost.includes("api.dev-stage.k12.aaic.dev")
? "34.123.93.40"
: undefined;
logger.info({ userId, investigationId, userName }, "WebSocket client connected");
// Setup handlers
setupPhysicsHandlers(client, { physicsEngineHost });
// Handle errors
ws.on("error", (error) => {
logger.error({ error }, "WebSocket error");
});
// Send connection ack
client.send("connected", { connectionId, userId });
logger.debug({ connectionId }, "WebSocket handlers registered");
}
Source