The DTP Sites web app development engine. https://digitaltelepresence.com/
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

178 lines
4.5 KiB

// dtp-media-engine.js
// Copyright (C) 2022 DTP Technologies, LLC
// All Rights Reserved
'use strict';
require('dotenv').config();
const path = require('path');
const mongoose = require('mongoose');
const mediasoup = require('mediasoup');
const { SiteAsync, SiteCommon, SitePlatform, SiteLog } = require(path.join(__dirname, 'lib', 'site-lib'));
module.rootPath = __dirname;
module.pkg = require(path.join(module.rootPath, 'package.json'));
module.config = {
component: { logId: 'dtp-media-engine', index: 'dtpMediaEngine', className: 'DtpMediaEngine' },
root: module.rootPath,
site: require(path.join(module.rootPath, 'config', 'site')),
webRtcServer: [
{
protocol: 'udp',
ip: process.env.MEDIASOUP_WEBRTC_BIND_ADDR || '127.0.0.1',
port: process.env.MEDIASOUP_WEBRTC_BIND_PORT || 20000,
}
]
};
module.log = new SiteLog(module, module.config.component);
class MediaEngineWorker extends SiteCommon {
constructor ( ) {
super(module, { logId: 'dtp-media-worker', index: 'dtpMediaWorker', className: 'MediaEngineWorker' });
this._id = mongoose.Types.ObjectId();
}
async start ( ) {
await super.start();
try {
this.worker = await mediasoup.createWorker({
logLevel: 'warn',
dtlsCertificateFile: process.env.HTTPS_SSL_CRT,
dtlsPrivateKeyFile: process.env.HTTPS_SSL_KEY,
});
} catch (error) {
throw new Error(`failed to start mediasoup worker process: ${error.message}`);
}
try {
const BIND_PORT = 20000 + module.nextWorkerIdx++;
this.webRtcServer = await this.worker.createWebRtcServer({
listenInfos: [
{
protocol: 'udp',
ip: '127.0.0.1',
port: BIND_PORT,
},
{
protocol: 'tcp',
ip: '127.0.0.1',
port: BIND_PORT,
},
],
});
} catch (error) {
throw new Error(`failed to start mediasoup WebRTC Server: ${error.message}`);
}
}
async stop ( ) {
if (this.webRtcServer && !this.webRtcServer.closed) {
this.log.info('closing mediasoup WebRTC server');
this.webRtcServer.close();
delete this.webRtcServer;
}
if (this.worker && !this.worker.closed) {
this.log.info('closing mediasoup worker process');
this.worker.close();
delete this.worker;
}
await super.stop();
}
}
module.onNewWorker = async (worker) => {
module.log.info('new worker created', { worker: worker.pid });
worker.observer.on('close', ( ) => {
module.log.info('worker shutting down', { worker: worker.pid });
});
worker.observer.on('newrouter', (router) => {
module.log.info('new router created', { worker: worker.pid, router: router.id });
router.observer.on('close', ( ) => {
module.log.info('router shutting down', { worker: worker.pid, router: router.id });
});
});
};
module.createWorker = async ( ) => {
const worker = new MediaEngineWorker();
module.workers.push(worker);
await worker.start();
};
module.shutdown = async ( ) => {
await SiteAsync.each(module.workers, async (worker) => {
try {
await worker.stop();
} catch (error) {
module.log.error('failed to stop worker', { error });
}
});
};
/*
* SERVER PROCESS INIT
*/
(async ( ) => {
process.on('unhandledRejection', (error, p) => {
module.log.error('Unhandled rejection', {
error: error,
promise: p,
stack: error.stack
});
});
process.on('warning', (error) => {
module.log.alert('warning', { error });
});
process.once('SIGINT', async ( ) => {
module.log.info('SIGINT received');
module.log.info('requesting shutdown...');
await module.shutdown();
const exitCode = await SitePlatform.shutdown();
process.nextTick(( ) => {
process.exit(exitCode);
});
});
process.once('SIGUSR2', async ( ) => {
await SitePlatform.shutdown();
process.kill(process.pid, 'SIGUSR2');
});
try {
await SitePlatform.start(module);
} catch (error) {
module.log.error(`failed to start DTP ${module.config.component.className} process`, { error });
return;
}
try {
module.log.info('registering mediasoup observer callbacks');
mediasoup.observer.on('newworker', module.onNewWorker);
module.log.info('creating mediasoup worker instance');
module.nextWorkerIdx = 0;
module.workers = [ ];
await module.createWorker();
module.log.info('DTP Media Engine online');
} catch (error) {
module.log.error('failed to start DTP Media Engine', { error });
process.exit(-1);
}
})();