This commit is contained in:
acgist
2023-02-04 17:01:00 +08:00
parent 75e7df522e
commit e477378d43
9 changed files with 119 additions and 92 deletions

View File

@@ -10,10 +10,9 @@
}, },
"dependencies": { "dependencies": {
"ws": "^8.12.0", "ws": "^8.12.0",
"debug": "^4.3.1" "debug": "^4.3.1",
"mediasoup": "file:./mediasoup"
}, },
"releaseDependencies": { "devDependencies": {
"mediasoup-local": "file:./mediasoup",
"mediasoup-online": "github:versatica/mediasoup#v3"
} }
} }

View File

@@ -2,6 +2,9 @@ const Logger = require("./Logger");
const logger = new Logger(); const logger = new Logger();
/**
* 交互式控制台
*/
function openCommandConsole() { function openCommandConsole() {
logger.info("打开交互式控制台..."); logger.info("打开交互式控制台...");
process.stdin.resume(); process.stdin.resume();

View File

@@ -133,5 +133,5 @@ module.exports = {
}, },
maxSctpMessageSize: 262144, maxSctpMessageSize: 262144,
}, },
}, }
}; };

View File

@@ -4,21 +4,20 @@
const debug = require("debug"); const debug = require("debug");
const config = require("./Config"); const config = require("./Config");
const APP_NAME = config.name;
class Logger { class Logger {
constructor(prefix) { constructor(prefix) {
const appName = config.name;
if (prefix) { if (prefix) {
this._debug = debug(`${APP_NAME}:${prefix}`); this._debug = debug(`${appName}:DEBUG:${prefix}`);
this._info = debug(`${APP_NAME}:INFO:${prefix}`); this._info = debug(`${appName}:INFO:${prefix}`);
this._warn = debug(`${APP_NAME}:WARN:${prefix}`); this._warn = debug(`${appName}:WARN:${prefix}`);
this._error = debug(`${APP_NAME}:ERROR:${prefix}`); this._error = debug(`${appName}:ERROR:${prefix}`);
} else { } else {
this._debug = debug(APP_NAME); this._debug = debug(`${appName}:DEBUG`);
this._info = debug(`${APP_NAME}:INFO`); this._info = debug(`${appName}:INFO`);
this._warn = debug(`${APP_NAME}:WARN`); this._warn = debug(`${appName}:WARN`);
this._error = debug(`${APP_NAME}:ERROR`); this._error = debug(`${appName}:ERROR`);
} }
this._debug.log = console.debug.bind(console); this._debug.log = console.debug.bind(console);
this._info.log = console.info.bind(console); this._info.log = console.info.bind(console);

View File

@@ -13,44 +13,33 @@ const command = require("./Command");
// 日志 // 日志
const logger = new Logger(); const logger = new Logger();
// 信令
const signal = new Signal(); const signal = new Signal();
// HTTPS server // HTTPS server
let httpsServer; let httpsServer;
// WebSocket server // WebSocket server
let webSocketServer; let webSocketServer;
// Mediasoup Worker列表 // Mediasoup Worker
const mediasoupWorkers = []; const mediasoupWorkers = [];
// Mediasoup Worker下个索引
let nextMediasoupWorkerIndex = 0;
process.title = config.name; process.title = config.name;
process.env.DEBUG = process.env.DEBUG || "*mediasoup* *INFO* *WARN* *ERROR*"; process.env.DEBUG = process.env.DEBUG || "*mediasoup* *INFO* *WARN* *ERROR*";
logger.info("开始启动:%s", config.name);
run(); /**
* 启动Mediasoup Worker
async function run() { */
// 启动Mediasoup服务 async function buildMediasoupWorkers() {
await runMediasoupWorkers();
// 启动服务
await runSignalServer();
logger.info("启动完成:%s", config.name);
// 交互式命令行
if (config.command) {
await command();
}
}
async function runMediasoupWorkers() {
const { numWorkers } = config.mediasoup; const { numWorkers } = config.mediasoup;
logger.info("启动Mediasoup服务%d Worker...", numWorkers); logger.info("启动Mediasoup服务%d Worker...", numWorkers);
for (let i = 0; i < numWorkers; i++) { for (let i = 0; i < numWorkers; i++) {
// 新建Worker
const worker = await mediasoup.createWorker({ const worker = await mediasoup.createWorker({
logLevel: config.mediasoup.workerSettings.logLevel, logLevel: config.mediasoup.workerSettings.logLevel,
logTags: config.mediasoup.workerSettings.logTags, logTags: config.mediasoup.workerSettings.logTags,
rtcMinPort: Number(config.mediasoup.workerSettings.rtcMinPort), rtcMinPort: Number(config.mediasoup.workerSettings.rtcMinPort),
rtcMaxPort: Number(config.mediasoup.workerSettings.rtcMaxPort), rtcMaxPort: Number(config.mediasoup.workerSettings.rtcMaxPort),
}); });
// 监听停止服务事件
worker.on("died", () => { worker.on("died", () => {
logger.error( logger.error(
"Mediasoup Worker停止服务两秒之后自动退出... [PID%d]", "Mediasoup Worker停止服务两秒之后自动退出... [PID%d]",
@@ -58,6 +47,7 @@ async function runMediasoupWorkers() {
); );
setTimeout(() => process.exit(1), 2000); setTimeout(() => process.exit(1), 2000);
}); });
// 加入队列
mediasoupWorkers.push(worker); mediasoupWorkers.push(worker);
// 配置WebRTC服务 // 配置WebRTC服务
if (process.env.MEDIASOUP_USE_WEBRTC_SERVER !== "false") { if (process.env.MEDIASOUP_USE_WEBRTC_SERVER !== "false") {
@@ -70,7 +60,7 @@ async function runMediasoupWorkers() {
const webRtcServer = await worker.createWebRtcServer(webRtcServerOptions); const webRtcServer = await worker.createWebRtcServer(webRtcServerOptions);
worker.appData.webRtcServer = webRtcServer; worker.appData.webRtcServer = webRtcServer;
} }
// 记录日志 // 定时记录使用日志
setInterval(async () => { setInterval(async () => {
const usage = await worker.getResourceUsage(); const usage = await worker.getResourceUsage();
logger.info( logger.info(
@@ -82,7 +72,10 @@ async function runMediasoupWorkers() {
} }
} }
async function runSignalServer() { /**
* 启动信令服务
*/
async function buildSignalServer() {
const tls = { const tls = {
cert: fs.readFileSync(config.https.tls.cert), cert: fs.readFileSync(config.https.tls.cert),
key: fs.readFileSync(config.https.tls.key), key: fs.readFileSync(config.https.tls.key),
@@ -119,12 +112,27 @@ async function runSignalServer() {
} }
}); });
}); });
logger.info("开启服务监听..."); // 打开监听
await new Promise((resolve) => {
httpsServer.listen( httpsServer.listen(
Number(config.https.listenPort), Number(config.https.listenPort),
config.https.listenIp, config.https.listenIp,
resolve () => {
logger.info("信令服务启动完成");
}
); );
});
} }
async function main() {
logger.info("开始启动:%s", config.name);
// 启动Mediasoup服务
await buildMediasoupWorkers();
// 启动服务
await buildSignalServer();
logger.info("启动完成:%s", config.name);
// 交互式命令行
if (config.command) {
await command();
}
}
main();

View File

@@ -3,19 +3,24 @@
* 1. 终端媒体流向 * 1. 终端媒体流向
* 2. 处理音频视频:降噪、水印等等 * 2. 处理音频视频:降噪、水印等等
*/ */
class Signal { class Signal {
// Mediasoup Worker列表
mediasoupWorkers = [];
// Mediasoup Worker下个索引
nextMediasoupWorkerIndex = 0;
constructor(mediasoupWorkers) {
this.mediasoupWorkers = mediasoupWorkers;
}
/** /**
* 处理事件 * 处理事件
* *
* @param {*} message 消息 * @param {*} message 消息
* @param {*} session websocket * @param {*} session websocket
*/ */
on(message, session) { on(message, session) {}
}
} }
module.exports = Signal; module.exports = Signal;

View File

@@ -133,5 +133,5 @@ module.exports = {
}, },
maxSctpMessageSize: 262144, maxSctpMessageSize: 262144,
}, },
}, }
}; };

View File

@@ -13,44 +13,33 @@ const command = require("./Command");
// 日志 // 日志
const logger = new Logger(); const logger = new Logger();
// 信令
const signal = new Signal(); const signal = new Signal();
// HTTPS server // HTTPS server
let httpsServer; let httpsServer;
// WebSocket server // WebSocket server
let webSocketServer; let webSocketServer;
// Mediasoup Worker列表 // Mediasoup Worker
const mediasoupWorkers = []; const mediasoupWorkers = [];
// Mediasoup Worker下个索引
let nextMediasoupWorkerIndex = 0;
process.title = config.name; process.title = config.name;
process.env.DEBUG = process.env.DEBUG || "*mediasoup* *INFO* *WARN* *ERROR*"; process.env.DEBUG = process.env.DEBUG || "*mediasoup* *INFO* *WARN* *ERROR*";
logger.info("开始启动:%s", config.name);
run(); /**
* 启动Mediasoup Worker
async function run() { */
// 启动Mediasoup服务 async function buildMediasoupWorkers() {
await runMediasoupWorkers();
// 启动服务
await runSignalServer();
logger.info("启动完成:%s", config.name);
// 交互式命令行
if (config.command) {
await command();
}
}
async function runMediasoupWorkers() {
const { numWorkers } = config.mediasoup; const { numWorkers } = config.mediasoup;
logger.info("启动Mediasoup服务%d Worker...", numWorkers); logger.info("启动Mediasoup服务%d Worker...", numWorkers);
for (let i = 0; i < numWorkers; i++) { for (let i = 0; i < numWorkers; i++) {
// 新建Worker
const worker = await mediasoup.createWorker({ const worker = await mediasoup.createWorker({
logLevel: config.mediasoup.workerSettings.logLevel, logLevel: config.mediasoup.workerSettings.logLevel,
logTags: config.mediasoup.workerSettings.logTags, logTags: config.mediasoup.workerSettings.logTags,
rtcMinPort: Number(config.mediasoup.workerSettings.rtcMinPort), rtcMinPort: Number(config.mediasoup.workerSettings.rtcMinPort),
rtcMaxPort: Number(config.mediasoup.workerSettings.rtcMaxPort), rtcMaxPort: Number(config.mediasoup.workerSettings.rtcMaxPort),
}); });
// 监听停止服务事件
worker.on("died", () => { worker.on("died", () => {
logger.error( logger.error(
"Mediasoup Worker停止服务两秒之后自动退出... [PID%d]", "Mediasoup Worker停止服务两秒之后自动退出... [PID%d]",
@@ -58,6 +47,7 @@ async function runMediasoupWorkers() {
); );
setTimeout(() => process.exit(1), 2000); setTimeout(() => process.exit(1), 2000);
}); });
// 加入队列
mediasoupWorkers.push(worker); mediasoupWorkers.push(worker);
// 配置WebRTC服务 // 配置WebRTC服务
if (process.env.MEDIASOUP_USE_WEBRTC_SERVER !== "false") { if (process.env.MEDIASOUP_USE_WEBRTC_SERVER !== "false") {
@@ -70,7 +60,7 @@ async function runMediasoupWorkers() {
const webRtcServer = await worker.createWebRtcServer(webRtcServerOptions); const webRtcServer = await worker.createWebRtcServer(webRtcServerOptions);
worker.appData.webRtcServer = webRtcServer; worker.appData.webRtcServer = webRtcServer;
} }
// 记录日志 // 定时记录使用日志
setInterval(async () => { setInterval(async () => {
const usage = await worker.getResourceUsage(); const usage = await worker.getResourceUsage();
logger.info( logger.info(
@@ -82,7 +72,10 @@ async function runMediasoupWorkers() {
} }
} }
async function runSignalServer() { /**
* 启动信令服务
*/
async function buildSignalServer() {
const tls = { const tls = {
cert: fs.readFileSync(config.https.tls.cert), cert: fs.readFileSync(config.https.tls.cert),
key: fs.readFileSync(config.https.tls.key), key: fs.readFileSync(config.https.tls.key),
@@ -119,12 +112,27 @@ async function runSignalServer() {
} }
}); });
}); });
logger.info("开启服务监听..."); // 打开监听
await new Promise((resolve) => {
httpsServer.listen( httpsServer.listen(
Number(config.https.listenPort), Number(config.https.listenPort),
config.https.listenIp, config.https.listenIp,
resolve () => {
logger.info("信令服务启动完成");
}
); );
});
} }
async function main() {
logger.info("开始启动:%s", config.name);
// 启动Mediasoup服务
await buildMediasoupWorkers();
// 启动服务
await buildSignalServer();
logger.info("启动完成:%s", config.name);
// 交互式命令行
if (config.command) {
await command();
}
}
main();

View File

@@ -3,19 +3,24 @@
* 1. 终端媒体流向 * 1. 终端媒体流向
* 2. 处理音频视频:降噪、水印等等 * 2. 处理音频视频:降噪、水印等等
*/ */
class Signal { class Signal {
// Mediasoup Worker列表
mediasoupWorkers = [];
// Mediasoup Worker下个索引
nextMediasoupWorkerIndex = 0;
constructor(mediasoupWorkers) {
this.mediasoupWorkers = mediasoupWorkers;
}
/** /**
* 处理事件 * 处理事件
* *
* @param {*} message 消息 * @param {*} message 消息
* @param {*} session websocket * @param {*} session websocket
*/ */
on(message, session) { on(message, session) {}
}
} }
module.exports = Signal; module.exports = Signal;