Mediasoup启动过程

一、启动server.js,调用createWorker方法创建进程

通过配置文件cpu数量创建worker,再createRouter,然后创建房间

server.js中
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)});worker.on('died', () =>{logger.error('mediasoup Worker died, exiting  in 2 seconds... [pid:%d]', worker.pid);setTimeout(() => process.exit(1), 2000);});mediasoupWorkers.push(worker);实例createRouter:static async create({ mediasoupWorker, roomId, consumerReplicas }){logger.info('create() [roomId:%s]', roomId);// Create a protoo Room instance.const protooRoom = new protoo.Room();// Router media codecs.const { mediaCodecs } = config.mediasoup.routerOptions;// Create a mediasoup Router.const mediasoupRouter = await mediasoupWorker.createRouter({ mediaCodecs });Worker.js中async createRouter({ mediaCodecs, appData } = {}) {logger.debug('createRouter()');if (appData && typeof appData !== 'object') {throw new TypeError('if given, appData must be an object');}// This may throw.const rtpCapabilities = ortc.generateRouterRtpCapabilities(mediaCodecs);const reqData = { routerId: (0, uuid_1.v4)() };await this.#channel.request('worker.createRouter', undefined, reqData);const data = { rtpCapabilities };const router = new Router_1.Router({internal: {routerId: reqData.routerId},data,channel: this.#channel,payloadChannel: this.#payloadChannel,appData});this.#routers.add(router);router.on('@close', () => this.#routers.delete(router));// Emit observer event.this.#observer.safeEmit('newrouter', router);return router;}

二、创建父子进程,实现 js与c++进程交互的通道

  constructor({ logLevel, logTags, rtcMinPort, rtcMaxPort, dtlsCertificateFile, dtlsPrivateKeyFile, libwebrtcFieldTrials, bweAllowableNotifyThreshold, appData }) {super();logger.debug('constructor()');let spawnBin = workerBin;let spawnArgs = [];if (process.env.MEDIASOUP_USE_VALGRIND === 'true') {spawnBin = process.env.MEDIASOUP_VALGRIND_BIN || 'valgrind';if (process.env.MEDIASOUP_VALGRIND_OPTIONS) {spawnArgs = spawnArgs.concat(process.env.MEDIASOUP_VALGRIND_OPTIONS.split(/\s+/));}spawnArgs.push(workerBin);}this.#child = (0, child_process_1.spawn)(// commandspawnBin, // argsspawnArgs, // options{env: {MEDIASOUP_VERSION: '3.11.13',// Let the worker process inherit all environment variables, useful// if a custom and not in the path GCC is used so the user can set// LD_LIBRARY_PATH environment variable for runtime....process.env},detached: false,// fd 0 (stdin)   : Just ignore it.// fd 1 (stdout)  : Pipe it for 3rd libraries that log their own stuff.// fd 2 (stderr)  : Same as stdout.// fd 3 (channel) : Producer Channel fd.// fd 4 (channel) : Consumer Channel fd.// fd 5 (channel) : Producer PayloadChannel fd.// fd 6 (channel) : Consumer PayloadChannel fd.stdio: ['ignore', 'pipe', 'pipe', 'pipe', 'pipe', 'pipe', 'pipe'],windowsHide: true});this.#pid = this.#child.pid;this.#channel = new Channel_1.Channel({producerSocket: this.#child.stdio[3],consumerSocket: this.#child.stdio[4],pid: this.#pid});

worker.js构造函数中创建父子进程,通过socket可以实现 JavaScript 与 C++ 之间的相互收发消息
this._child = child_process_1.spawn(   spawnBin,    spawnArgs,  


使用 child_process.spawn() 方法创建了一个子进程,并将它赋值给 this.#child。spawn() 方法接受三个参数:

spawnBin:要执行的命令或可执行文件的路径。
spawnArgs:传递给命令的参数数组。
options:一个对象,用于配置子进程的选项。

options 对象中的一些重要配置包括:

env:指定子进程的环境变量。这里设置了 MEDIASOUP_VERSION 变量,并将父进程的环境变量继承给子进程。
detached:指定子进程是否独立运行,即与父进程无关。
stdio:指定子进程的标准输入、输出和错误流的处理方式。这里使用管道 (pipe) 来处理子进程的输出和错误。
windowsHide:在 Windows 系统中隐藏子进程的控制台窗口

this.#channel = new Channel_1.Channel({producerSocket: this.#child.stdio[3],consumerSocket: this.#child.stdio[4],pid: this.#pid});await this.#channel.request('worker.createRouter', undefined, reqData);调用channel的request与C++进程通信

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/75794.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【ARM CoreLink 系列 2 -- CCI-400 控制器简介】

文章目录 CCI-400 介绍DVM 机制介绍DVM 消息传输过程TOKEN 机制介绍 下篇文章&#xff1a;ARM CoreLink 系列 3 – CCI-550 控制器介绍 CCI-400 介绍 CCI&#xff08;Cache Coherent Interconnect&#xff09;是ARM 中 的Cache一致性控制器。 CCI-400 将 Interconnect 和coh…

Swift的可选类型Optional

1、Optional类型的概念 可选类型用来表示“有一个值&#xff0c;它等于x或者根本没有值”。当我们遇到Optional类型时&#xff0c;就会明显知道这里的值可能为nil&#xff0c;我们必须谨慎处理。 2、Optional类型的实现 var optionalInteger: Int? //或者 var optionalInte…

Ajax + Promise复习简单小结simple

axios使用 先看看老朋友 axios axios是基于Ajaxpromise封装的 看一下他的简单使用 安装&#xff1a;npm install axios --save 引入&#xff1a;import axios from axios GitHub地址 基本使用 axios({url: http://hmajax.itheima.net/api/province}).then(function (result…

重要公告|投票委托已经上线,应该如何选择社区代表?

社区代表是Token持有者委托投票权的个人或团体&#xff0c;可以代表Token持有者在Moonbeam治理中投票。委托是可选的&#xff0c;允许代表在治理过程中代表更大比例的Token和Token持有者。相比社区代表&#xff0c;不愿投票的Token持有者可以将投票权委托给社区代表&#xff0c…

C语言学习系列-->字符函数和字符串函数

文章目录 一、字符函数1、字符分类函数2、字符转换函数 二、字符串函数1、strlen概述模拟实现 2、strcpy概述模拟实现 3、strcat概述模拟实现 3、strcmp概述模拟实现 4、有限制的字符串函数strncpystrncatstrncmp 4、strstr概述模拟实现 一、字符函数 1、字符分类函数 包含头…

vue3:22、vue-router的使用

import { createRouter, createWebHistory } from vue-router//history模式&#xff1a;createWebHistory //hash模式&#xff1a;createWebHashHistory//vite中的环境变量 import.meta.env.BASE_URL 就是vite.config.js中的base配置项 const router createRouter({history:…

Spring Data JPA:简化数据库交互的艺术

&#x1f337;&#x1f341; 博主猫头虎&#xff08;&#x1f405;&#x1f43e;&#xff09;带您 Go to New World✨&#x1f341; &#x1f984; 博客首页——&#x1f405;&#x1f43e;猫头虎的博客&#x1f390; &#x1f433; 《面试题大全专栏》 &#x1f995; 文章图文…

lv3 嵌入式开发-11 Linux下GDB调试工具

目录 1 GDB简介 2 GDB基本命令 3 GDB调试程序 1 GDB简介 GDB是GNU开源组织发布的一个强大的Linux下的程序调试工具。 一般来说&#xff0c;GDB主要帮助你完成下面四个方面的功能&#xff1a; 1、启动你的程序&#xff0c;可以按照你的自定义的要求随心所欲的运行程序&#…

【leetcode 力扣刷题】回文串相关题目(KMP、动态规划)

回文串相关题目 5. 最长回文子串动态规划中心扩展算法 214. 最短回文串336. 回文对 5. 最长回文子串 题目链接&#xff1a;5. 最长回文子串 题目内容&#xff1a; 题目就是要我们找s中的回文子串&#xff0c;还要是最长的。其实想想&#xff0c;暴力求解也行……就是遍历所有的…

Python编程的八大魔法库

Python是一门广受欢迎的编程语言&#xff0c;其生态系统丰富多彩&#xff0c;拥有许多令人惊叹的依赖库&#xff0c;可以帮助程序员们在各种领域中创造出令人瞠目结舌的应用。在这篇文章中&#xff0c;我们将探讨Python编程的十大神奇依赖库&#xff0c;它们像魔法一样&#xf…

springfox及springdoc

open api 简介 OpenApi是一个业界的 API 文档标准&#xff0c;一个规范&#xff0c;提供了一种标准的方式来描述API的结构、参数、响应等信息。springfox和springdoc是用在Spring框架中生成和展示OpenApi文档的工具 springfox springfox基于Spring框架的库&#xff0c;提供注…

jmeter 计数器Counter

计数器可以用于生成动态的数值或字符串&#xff0c;以模拟不同的用户或数据。 计数器通常与用户线程组结合使用&#xff0c;以生成不同的变量值并在测试中应用。以下是计数器的几个常用属性&#xff1a; 变量前缀&#xff08;Variable Name Prefix&#xff09;&#xff1a;定义…

G. The Morning Star

Problem - G - Codeforces 思路&#xff1a;想了挺长时间的&#xff0c;一直没想到一个简便的方法在瞎搞。我们发现对于某个点来说&#xff0c;其他的点如果能够跟他匹配&#xff0c;那么一定在这8个方向上&#xff0c;而同时这8个方向其实对应这4条直线&#xff0c;假设点为(x…

静态路由 网络实验

静态路由 网络实验 拓扑图初步配置R1 ip 配置R2 ip 配置R3 ip 配置查看当前的路由表信息查看路由表信息配置静态路由测试 拓扑图 需求&#xff1a;实现 ip 192.168.1.1 到 192.168.2.1 的通信。 初步配置 R1 ip 配置 system-view sysname R1 undo info-center enable # 忽略…

C语言经典100例题(55)--从一个整数a中把从右端开始的4-7位取出来

目录 题目 问题分析 右移操作符 左移操作符 方法一 方法二 运行结果 题目 用c语言从一个整数a中把从右端开始的4-7位取出来 问题分析 右移操作符 右移操作符是一种位运算符&#xff0c;用于将二进制数向右移动指定的位数。它通常用符号" >> "表示…

W11下CMake MinGW配置OpenCV和Qt

&#x1f482; 个人主页:风间琉璃&#x1f91f; 版权: 本文由【风间琉璃】原创、在CSDN首发、需要转载请联系博主&#x1f4ac; 如果文章对你有帮助、欢迎关注、点赞、收藏(一键三连)和订阅专栏哦 前言 前几天将cuda版本的opencv给编译成功了&#xff0c;当时用的VS的MSVC&…

python包导入原理解析

原文链接&#xff1a; https://www.cnblogs.com/hi3254014978/p/15317976.html 根据编程经验的不同&#xff0c;我们在运行程序时可能经常或者偶尔碰到下面这些问题&#xff0c;仔细观察后会发现这些问题无一例外都出现了一个相同的短语&#xff0c;很容易就可以发现&#xff0…

day37 线程

一、线程安全 二、多线程并发的安全问题 当多个线程并发操作同一临界资源 由于线程切换实际不确定 导致操作顺序出现混乱 产生的程序bug 严重时出现系统瘫痪 临界资源 &#xff1a;操作该资源的完整流程同一时间只能被单一线程操作的资源 多线程并发会出现的各种问题、 如…

聊聊 HTMX 吧

写在前面 最近看了几篇关于 htmx 的文章&#xff0c;自己也去看了一眼官网&#xff0c;也去油管看了一下当时 htmx 发布会的时候他们的演示&#xff0c;下面说几点我对这个所谓的新型起来的技术的看法&#xff0c; 他的来源是什么 首先说一下他虽然是一个新型的技术&#xff0c…

jQuery选择器参考手册

选择器实例选取*$(“*”)所有元素#id$(“#lastname”)id“lastname” 的元素.class$(“.intro”)class“intro” 的所有元素.class,.class$(“.intro,.demo”)class 为 “intro” 或 “demo” 的所有元素element$(“p”)所有 <p> 元素el1,el2,el3$(“h1,div,p”)所有 <…