refactor: extract websocket server
This commit is contained in:
+10
-38
@@ -9,7 +9,6 @@ import express, {
|
|||||||
type Response,
|
type Response,
|
||||||
} from "express";
|
} from "express";
|
||||||
import helmet from "helmet";
|
import helmet from "helmet";
|
||||||
import { WebSocketServer } from "ws";
|
|
||||||
import { config } from "./config";
|
import { config } from "./config";
|
||||||
import { AppError } from "./errors";
|
import { AppError } from "./errors";
|
||||||
import { createChildLogger, logger } from "./logger";
|
import { createChildLogger, logger } from "./logger";
|
||||||
@@ -37,7 +36,7 @@ import {
|
|||||||
exposePcmBroadcastGlobal,
|
exposePcmBroadcastGlobal,
|
||||||
exposeVideoBroadcastGlobal,
|
exposeVideoBroadcastGlobal,
|
||||||
} from "./ws/broadcastGlobals";
|
} from "./ws/broadcastGlobals";
|
||||||
import { createVoiceAudioBridge } from "./ws/voiceAudioBridge";
|
import { startWebSocketServer } from "./ws/server";
|
||||||
|
|
||||||
const __filename = fileURLToPath(import.meta.url);
|
const __filename = fileURLToPath(import.meta.url);
|
||||||
const __dirname = path.dirname(__filename);
|
const __dirname = path.dirname(__filename);
|
||||||
@@ -61,8 +60,6 @@ export async function startWebserver(
|
|||||||
const server = http.createServer(app);
|
const server = http.createServer(app);
|
||||||
|
|
||||||
const wsPath = "/ws";
|
const wsPath = "/ws";
|
||||||
const wss = new WebSocketServer({ server, path: wsPath });
|
|
||||||
wsLogger.info({ port, wsPath }, "WebSocket server listening");
|
|
||||||
|
|
||||||
// Create broadcaster instance
|
// Create broadcaster instance
|
||||||
const broadcaster = createBroadcaster();
|
const broadcaster = createBroadcaster();
|
||||||
@@ -205,40 +202,15 @@ export async function startWebserver(
|
|||||||
exposeVideoBroadcastGlobal(() => broadcaster.getClients(), wsLogger);
|
exposeVideoBroadcastGlobal(() => broadcaster.getClients(), wsLogger);
|
||||||
exposeActiveUserGlobal(activeUsers, broadcastUserState);
|
exposeActiveUserGlobal(activeUsers, broadcastUserState);
|
||||||
|
|
||||||
const voiceAudioBridge = createVoiceAudioBridge(wsLogger);
|
startWebSocketServer({
|
||||||
|
server,
|
||||||
wss.on("connection", (ws) => {
|
port,
|
||||||
wsLogger.info({ port, wsPath }, "New WebSocket connection");
|
wsPath,
|
||||||
broadcaster.addClient(ws);
|
broadcaster,
|
||||||
|
activeUsers,
|
||||||
ws.send(
|
getSharedUIState,
|
||||||
JSON.stringify({
|
mediaController,
|
||||||
type: "user_state",
|
logger: wsLogger,
|
||||||
users: Array.from(activeUsers.entries()).map(([id, data]) => ({
|
|
||||||
id,
|
|
||||||
...data,
|
|
||||||
})),
|
|
||||||
}),
|
|
||||||
);
|
|
||||||
ws.send(JSON.stringify({ type: "ui_state", state: getSharedUIState() }));
|
|
||||||
ws.send(
|
|
||||||
JSON.stringify({
|
|
||||||
type: "media_state",
|
|
||||||
state: mediaController.getState(),
|
|
||||||
}),
|
|
||||||
);
|
|
||||||
|
|
||||||
ws.on("message", (data: Buffer | ArrayBuffer | Buffer[]) => {
|
|
||||||
if (!Buffer.isBuffer(data)) return;
|
|
||||||
voiceAudioBridge.handleBrowserAudio(data);
|
|
||||||
});
|
|
||||||
|
|
||||||
ws.on("close", () => {
|
|
||||||
broadcaster.removeClient(ws);
|
|
||||||
});
|
|
||||||
ws.on("error", () => {
|
|
||||||
broadcaster.removeClient(ws);
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
app.use(
|
app.use(
|
||||||
|
|||||||
@@ -0,0 +1,78 @@
|
|||||||
|
import type { Server as HttpServer } from "node:http";
|
||||||
|
import { WebSocketServer } from "ws";
|
||||||
|
import type { createChildLogger } from "../logger";
|
||||||
|
import type { MediaController } from "../media/mediaController";
|
||||||
|
import type { ModerationBroadcaster } from "../moderation/types";
|
||||||
|
import { createVoiceAudioBridge } from "./voiceAudioBridge";
|
||||||
|
|
||||||
|
type Logger = ReturnType<typeof createChildLogger>;
|
||||||
|
|
||||||
|
type ActiveUsers = Map<
|
||||||
|
string,
|
||||||
|
{ username: string; avatar: string; speaking: boolean }
|
||||||
|
>;
|
||||||
|
|
||||||
|
export interface WebSocketServerOptions {
|
||||||
|
server: HttpServer;
|
||||||
|
port: number;
|
||||||
|
wsPath: string;
|
||||||
|
broadcaster: ModerationBroadcaster;
|
||||||
|
activeUsers: ActiveUsers;
|
||||||
|
getSharedUIState: () => unknown;
|
||||||
|
mediaController: MediaController;
|
||||||
|
logger: Logger;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function startWebSocketServer(options: WebSocketServerOptions) {
|
||||||
|
const wss = new WebSocketServer({
|
||||||
|
server: options.server,
|
||||||
|
path: options.wsPath,
|
||||||
|
});
|
||||||
|
const voiceAudioBridge = createVoiceAudioBridge(options.logger);
|
||||||
|
|
||||||
|
options.logger.info(
|
||||||
|
{ port: options.port, wsPath: options.wsPath },
|
||||||
|
"WebSocket server listening",
|
||||||
|
);
|
||||||
|
|
||||||
|
wss.on("connection", (ws) => {
|
||||||
|
options.logger.info(
|
||||||
|
{ port: options.port, wsPath: options.wsPath },
|
||||||
|
"New WebSocket connection",
|
||||||
|
);
|
||||||
|
options.broadcaster.addClient(ws);
|
||||||
|
|
||||||
|
ws.send(
|
||||||
|
JSON.stringify({
|
||||||
|
type: "user_state",
|
||||||
|
users: Array.from(options.activeUsers.entries()).map(([id, data]) => ({
|
||||||
|
id,
|
||||||
|
...data,
|
||||||
|
})),
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
ws.send(
|
||||||
|
JSON.stringify({ type: "ui_state", state: options.getSharedUIState() }),
|
||||||
|
);
|
||||||
|
ws.send(
|
||||||
|
JSON.stringify({
|
||||||
|
type: "media_state",
|
||||||
|
state: options.mediaController.getState(),
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
|
ws.on("message", (data: Buffer | ArrayBuffer | Buffer[]) => {
|
||||||
|
if (!Buffer.isBuffer(data)) return;
|
||||||
|
voiceAudioBridge.handleBrowserAudio(data);
|
||||||
|
});
|
||||||
|
|
||||||
|
ws.on("close", () => {
|
||||||
|
options.broadcaster.removeClient(ws);
|
||||||
|
});
|
||||||
|
ws.on("error", () => {
|
||||||
|
options.broadcaster.removeClient(ws);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
return wss;
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user