mediasoup源码分析(二)--worker启动

信令服务进程启动worker进程

1.官方demo提供的启动方式

官方提供的mediasoup-demo是由js(信令)+c++(流媒体服务)两部分服务,mediasoup的worker进程是nodejs通过child_process 的spawn()接口启动的

打开server.js 文件

go 复制代码
server.js文件
async function run()
{
    // Open the interactive server.
    await interactiveServer();

    // Open the interactive client.
    if (process.env.INTERACTIVE === 'true' || process.env.INTERACTIVE === '1')
    await interactiveClient();

    // Run a mediasoup Worker.
    await runMediasoupWorkers(); //内部会创建worker

    // Create Express app.
    await createExpressApp();

    // Run HTTPS server.
    await runHttpsServer();

    // Run a protoo WebSocketServer.
    await runProtooWebSocketServer();

    // Log rooms status every X seconds.
    setInterval(() =>
                {
                    for (const room of rooms.values())
                    {
                        room.logStatus();
                    }
                }, 120000);
}

runMediasoupWorkers()函数,首先获得当前机器cpu核数,有几核就创建几个woker

go 复制代码
// Number of mediasoup workers to launch.
numWorkers : Object.keys(os.cpus()).length,

创建woker的函数

go 复制代码
async function runMediasoupWorkers()
{
    const { numWorkers } = config.mediasoup;

    logger.info('running %d mediasoup Workers...', numWorkers);

    for (let i = 0; i < numWorkers; ++i)
    {
        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)
            });
        .....
        .....
    }

最终代码会调用到 mediasoup-demo/server/node_modules/mediasoup/src/index.ts中的createWorker()函数

go 复制代码
export async function createWorker(
    ......
    ......
    const worker = new Worker(
        {
            logLevel,
            logTags,
            rtcMinPort,
            rtcMaxPort,
            dtlsCertificateFile,
            dtlsPrivateKeyFile,
            appData
        });

    .....

    )

代码调用到 mediasoup-demo/server/node_modules/mediasoup/src/Worker.ts文件

node.js 通过spawn启动mediasoup-worker进程,spawn学习:https://www.runoob.com/nodejs/nodejs-process.html

go 复制代码
Woker的构造函数
this._child = spawn(
    // command
    spawnBin,
    // args
    spawnArgs,
    // options

    //同时创建用于通信的管道
    this._channel = new Channel(
        {
            producerSocket : this._child.stdio[3],
            consumerSocket : this._child.stdio[4],
            pid            : this._pid
        });

    producerSocket   stdio[3] 用来发送数据给子进程,consumerSocket  stdio[4] 用来接收数据
    如果给worker发送消息,详情见Channel.ts
    // This may throw if closed or remote side ended.
    this._producerSocket.write(ns);

    同时也创建了PayloadChannel
    this._payloadChannel = new PayloadChannel(
        {
            // NOTE: TypeScript does not like more than 5 fds.
            // @ts-ignore
            producerSocket : this._child.stdio[5],
            // @ts-ignore
            consumerSocket : this._child.stdio[6]
        });

mediasoup是根据当前机器cpu核数,选择创建几个worker进程

跳转到mediasoup-demo/server/node_modules/mediasoup/src/index.ts

在跳转到mediasoup-demo/server/node_modules/mediasoup/src/Worker.ts

2.自行启动mediasoup

如果读者仅仅是需要学习mediasoup c++部分,则可以编辑脚本启动mediasoup服务

参考:

vim config.ini

bash 复制代码
[General]
servercount = 2

[Server0]
id = 1
udpport = 52000
ip = 127.0.0.1
vrvmeetingport = 8108

[Server1]
id = 2
udpport = 53000
ip = 127.0.0.1
vrvmeetingport = 8108

vim start.sh

bash 复制代码
 #!/bin/bash
ulimit -c unlimited
configFile="./config.ini"
function ReadINIfile()
{
    Key=$1
    Section=$2
    Configfile=$3
    ReadINI=`awk -F '=' '/\['$Section'\]/{a=1}a==1&&$1~/'$Key'/{print $2;exit}' $Configfile`
    echo "$ReadINI"
}

serverCount=`ReadINIfile "servercount" "General" "$configFile"`
for((i=0; i<serverCount; i++))
do
    Section="Server""$i"
    id=`ReadINIfile "id" "$Section" "$configFile"  | sed -e 's/^[ \t]*//g'`
    udpPort=`ReadINIfile "udpport" "$Section" "$configFile"  | sed -e 's/^[ \t]*//g'`
    vrvmeetingIp=`ReadINIfile "vrvmeetingip" "$Section" "$configFile" | sed -e 's/^[ \t]*//g'`
    vrvmeetingPort=`ReadINIfile "vrvmeetingport" "$Section" "$configFile"  | sed -e 's/^[ \t]*//g'`
    iperfPort=`ReadINIfile "iperfport" "$Section" "$configFile"  | sed -e 's/^[ \t]*//g'`

    nohup ./rtcMediaServer $id $vrvmeetingIp $vrvmeetingPort $iperfPort --logLevel=debug --logTag=info --logTag=ice --logTag=dtls --logTag=rtp --logTag=srtp --logTag=rtcp --logTag=rbe --logTag=rtx --rtcIPv4=true --rtcIPv6=false --singlePort=true --getkeyframe=5000 --rtcMinPort=$udpPort --rtcMaxPort=65535 & echo $! >> pid
done

执行sh start.sh

至此,mediasoup的worker进程已经成功启动

随后梳理mediasoup中的worker创建

相关推荐
嵌入式小章4 小时前
基于STM32的实时时钟(RTC)教学
stm32·嵌入式硬件·实时音视频
wenchm4 天前
细说STM32单片机USART中断收发RTC实时时间并改善其鲁棒性的方法
stm32·单片机·实时音视频
Starry-sky(jing)6 天前
边缘计算【智能+安全检测】系列教程--agx orin解决RTC时间问题
linux·人工智能·目标检测·边缘计算·实时音视频
weichushun7 天前
STM32 RTC时间无法设置和读取
stm32·嵌入式硬件·实时音视频
LightningJie8 天前
STM32的hal库在实现延时函数(例如:Delay_ms 等)为什么用滴答定时(Systick)而不是定时器定时中断,也不是RTC?
stm32·单片机·实时音视频
Tracy97312 天前
空间音频技术
大数据·人工智能·音视频·语音识别·实时音视频
棱角~~13 天前
市面上热门的四款PDF转换器解析!!
人工智能·其他·pdf·音视频·实时音视频·学习方法
音视频牛哥13 天前
480p 720p 1080p 2k 4k 8k 12k分辨率视频分别占用多大带宽?
音视频·实时音视频·大牛直播sdk·8k编码·12k编码·rtmp 4k·rtmp 8k
棱角~~14 天前
百度翻译以及另外三款翻译工具推荐!!!
前端·经验分享·其他·音视频·实时音视频·1024程序员节