119 lines
3.6 KiB
TypeScript
119 lines
3.6 KiB
TypeScript
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;
|
||
}
|
||
};
|
||
});
|
||
}
|
||
}
|