Files
taoyao/taoyao-media-server/src/Server.js
2023-02-14 08:14:23 +08:00

193 lines
5.3 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/usr/bin/env node
const fs = require("fs");
const ws = require("ws");
const https = require("https");
// const mediasoup = require("mediasoup");
const config = require("./Config");
const Logger = require("./Logger");
const Signal = require("./Signal");
const { fail } = require("assert");
// 线程名称
process.title = config.name;
// 无效信令终端列表
const clients = [];
// Mediasoup Worker列表
const mediasoupWorkers = [];
// HTTPS server
let httpsServer;
// WebSocket server
let webSocketServer;
// 日志
const logger = new Logger();
// 信令
const signal = new Signal(mediasoupWorkers);
/**
* 启动Mediasoup Worker
*/
async function buildMediasoupWorkers() {
const { workerSize } = config.mediasoup;
logger.info("启动Mediasoup Worker", workerSize);
for (let i = 0; i < workerSize; i++) {
// 新建Worker
const worker = await mediasoup.createWorker({
logLevel: config.mediasoup.workerSettings.logLevel,
logTags: config.mediasoup.workerSettings.logTags,
rtcMinPort: Number(config.mediasoup.workerSettings.rtcMinPort),
rtcMaxPort: Number(config.mediasoup.workerSettings.rtcMaxPort),
});
// 监听Worker事件
worker.on("died", () => {
logger.warn("Mediasoup Worker停止服务", worker.pid);
setTimeout(() => process.exit(1), 2000);
});
// 加入Worker队列
mediasoupWorkers.push(worker);
// 配置WebRTC服务
if (process.env.MEDIASOUP_USE_WEBRTC_SERVER !== "false") {
// 配置Worker端口
const portIncrement = mediasoupWorkers.length - 1;
const webRtcServerOptions = JSON.parse(
JSON.stringify(config.mediasoup.webRtcServerOptions)
);
for (const listenInfo of webRtcServerOptions.listenInfos) {
listenInfo.port += portIncrement;
}
// 配置WebRTC服务
const webRtcServer = await worker.createWebRtcServer(webRtcServerOptions);
worker.appData.webRtcServer = webRtcServer;
}
// 定时记录使用日志
setInterval(async () => {
const usage = await worker.getResourceUsage();
logger.info("Mediasoup Worker使用情况", worker.pid, usage);
}, 120 * 1000);
}
}
/**
* 启动信令服务
*/
async function buildSignalServer() {
const tls = {
cert: fs.readFileSync(config.https.tls.cert),
key: fs.readFileSync(config.https.tls.key),
};
// 配置HTTPS
httpsServer = https.createServer(tls, (request, response) => {
response.writeHead(200);
response.end(fs.readFileSync(config.welcome));
});
// 配置WebSocket
webSocketServer = new ws.Server({ server: httpsServer });
webSocketServer.on("connection", (session) => {
logger.info("打开信令通道", session._socket.remoteAddress);
session.datetime = Date.now();
session.authorize = false;
clients.push(session);
session.on("close", (code) => {
logger.info("关闭信令通道", session._socket.remoteAddress, code);
});
session.on("error", (error) => {
logger.error("信令通道异常", session._socket.remoteAddress, error);
});
session.on("message", (message) => {
logger.debug("处理信令消息", message.toString());
try {
signal.on(JSON.parse(message), session);
} catch (error) {
logger.error("处理信令消息异常", message.toString(), error);
}
});
});
// 打开监听
httpsServer.listen(
Number(config.https.listenPort),
config.https.listenIp,
() => {
logger.info("信令服务启动完成");
}
);
}
/**
* 定时清理无效信令终端
*/
async function buildClientInterval() {
setInterval(() => {
const datetime = Date.now();
let failSize = 0;
let successSize = 0;
for (let i = 0; i < clients.length; i++) {
const session = clients[i];
// 超过五秒自动关闭
if (datetime - session.datetime >= 5000) {
clients.splice(i, 1);
if(session.authorize) {
successSize++;
} else {
failSize++;
session.close();
}
i--;
}
}
logger.info("定时清理无效信令终端", failSize, successSize, clients.length);
}, 60 * 1000);
}
/**
* 交互式控制台
*/
async function buildCommandConsole() {
if (!config.command) {
return;
}
process.stdin.setEncoding("UTF-8");
process.stdin.resume();
process.stdin.on("data", (data) => {
process.stdin.pause();
const command = data.replace(/^\s*/, "").replace(/\s*$/, "");
logger.info("");
switch (command) {
case "h":
case "help": {
logger.info("- h, help 帮助信息");
logger.info("- os 系统信息");
break;
}
case "":
default: {
logger.warn(`未知命令:'${command}'`);
logger.info("查询命令:'h' | 'help'");
break;
}
}
logger.info("");
process.stdin.resume();
});
}
/**
* 启动方法
*/
async function main() {
logger.debug("闹市早行客");
logger.info("江边独钓翁");
logger.warn("山中与谁同");
logger.error("绿竹细雨风");
logger.info("开始启动", config.name);
// await buildMediasoupWorkers();
await buildSignalServer();
await buildClientInterval();
await buildCommandConsole();
logger.info("启动完成", config.name);
}
// 启动服务
main();