import * as websocket from "ws"; import { Server as HttpServer } from 'http'; import { Server as HttpsServer } from 'https'; import * as handler from "./class/websockethandler"; import { log, LogLevel } from './log'; export default class WSSignaling { server: HttpServer | HttpsServer; wss: websocket.Server; /** * 构造函数,初始化WebSocket信令服务器 * @param server HTTP服务器实例 * @param mode 通信模式(public或private) */ constructor(server: HttpServer | HttpsServer, mode: string) { // 保存服务器实例 this.server = server; // 创建WebSocket服务器 this.wss = new websocket.Server({ server }); // 重置处理器,设置通信模式 handler.reset(mode); /** * 监听WebSocket连接事件 * @param ws WebSocket连接实例 */ this.wss.on('connection', (ws: WebSocket) => { // 添加新的WebSocket连接到处理器 handler.add(ws); //handler.AddHeartbeat(ws); /** * 监听连接关闭事件 */ ws.onclose = (): void => { // 从处理器中移除关闭的连接 handler.remove(ws); //handler.RemoveHeartbeat(ws); }; /** * 监听消息事件 * @param event 消息事件对象 */ ws.onmessage = (event: MessageEvent): void => { // 消息类型说明: // 1. connect, disconnect 消息格式: // { type: "connect", connectionId: "连接ID" } // { type: "disconnect", connectionId: "连接ID" } // 2. offer, answer, candidate 消息格式: // { // type: "offer", // data: { // from: "发送方连接ID", // to: "接收方连接ID", // data: "信令数据" // } // } // 3. broadcast 消息格式: // { // type: "broadcast", // message: "广播消息内容", // targetConnectionId: "目标连接ID(可选)" // } // 解析消息数据 const msg = JSON.parse(event.data); // 检查消息是否有效 if (!msg || !this) { return; } // 打印接收到的消息 log(LogLevel.log, 'WS received:', msg); // 根据消息类型处理 switch (msg.type) { case "connect": handler.onConnect(ws, msg.connectionId); break; case "disconnect": handler.onDisconnect(ws, msg.connectionId); break; case "offer": if (msg.participantId !== undefined) msg.data.participantId = msg.participantId; handler.onOffer(ws, msg.data); break; case "answer": if (msg.participantId !== undefined) msg.data.participantId = msg.participantId; handler.onAnswer(ws, msg.data); break; case "candidate": if (msg.participantId !== undefined) msg.data.participantId = msg.participantId; handler.onCandidate(ws, msg.data); break; case "ping": ws.send(JSON.stringify({ type: "pong" })); break; case "pong": (ws as any).lastActivity = Date.now(); break; case "broadcast": handler.onBroadcast(ws, msg.data); break; case 'call-request': handler.onCallConnectionId(ws, msg.data); break; case 'on-message': if (msg.from) msg.data.connectionId = msg.from; handler.onMessage(ws, msg.data); break; default: break; } }; }); } }