const {spawn, fork} = require('node:child_process') const is_running = require('is-running') const config = require('../../config') const webrtc_server_path = config.webrtc_server_path const sfu_server_path = config.sfu_server_path const app_args_static = config.app_args.static const app_port_arg = config.app_args.runtime.port const fs = require('fs') const tcp_port_used = require('tcp-port-used') const webrtc_timeout = 60000 const webrtc_retry_time = 100 const is_proc_running = (pid) => { return is_running(pid) } const is_proc_running_async = async (pid, time_ms) => { let timeout_count = 0 let check_times = 10 while (true) { ++timeout_count if (!is_proc_running(pid)) { return false } if (timeout_count > check_times) { return true } await new Promise(resolve => setTimeout(resolve, time_ms / check_times)) } } const run_webrtc = async (webrtc_port, app_port, sfu_port, session_server_url, session_id) => { if (!fs.existsSync(webrtc_server_path)) { return null } let webrtc_proc try { let webrtc_proc_arg = JSON.stringify({webrtc_port:webrtc_port, app_port:app_port, sfu_port:sfu_port, session_server_url:session_server_url, session_id:session_id}) webrtc_proc = fork(webrtc_server_path, [webrtc_proc_arg], { detached: true }) await tcp_port_used.waitUntilUsed(webrtc_port, webrtc_retry_time, webrtc_timeout) } catch (err) { console.error(err) return null } //let proc_status = await is_proc_running_async(webrtc_proc.pid, 500) return (webrtc_proc) ? webrtc_proc.pid : null } const run_app = async (app_path, app_port) => { let app_proc try { app_proc = spawn(app_path, [].concat(app_args_static, [app_port_arg + app_port.toString()], { cwd: './', stdio: ['ignore', 'pipe', 'pipe']}), { detached: true }) // bind some events to unfreez process app_proc.stdout.on('data', data => { //console.log('stdout: ' + data.toString()); }) app_proc.stderr.on('data', data => { //console.log('stderr: ' + data.toString()); }) } catch (err) { return null } return (app_proc) ? app_proc.pid : null } const run_sfu = async (sfu_port) => { if (!fs.existsSync(sfu_server_path)) { return null } let sfu_proc try { let sfu_proc_arg = JSON.stringify({sfu_port:sfu_port}) sfu_proc = fork(sfu_server_path, [sfu_proc_arg], { detached: true }) //await tcp_port_used.waitUntilUsed(webrtc_port, webrtc_retry_time, webrtc_timeout) } catch (err) { console.error(err) return null } //let proc_status = await is_proc_running_async(webrtc_proc.pid, 500) return (sfu_proc) ? sfu_proc.pid : null } const kill_proc = (pid) => { if (!is_proc_running(pid)) { return } if (process.platform === 'win32') { spawn('taskkill', ['/pid', pid, '/f', '/t'], { shell: false, detached: true, stdio: 'ignore', windowsHide: true }) } else { process.kill(pid) } } module.exports = { run_webrtc, run_app, run_sfu, is_proc_running, is_proc_running_async, kill_proc }