Mediasoup在node.js下多线程实现

mediasoup基于socket.io的交互消息来完成join-room的请求过程。Join的过程,实际就是获取stream的过程,也就是视频加载时间(video-load-speed)。在RTMP系统,视频加载时间是秒开。Mediasoup给出的第一个frame是I-frame,但由于交互的消息较多(8条),node.js是单线程处理框架,并发处理能力明显不足。即使50个并发,也有超过20%的用户视频加载时间>1000ms。

Join-room的过程,由8条消息组成:

#1: roomEventHandler:createRoom,roomId=demo-ch-12

#2: roomEventHandler:join,roomId=demo-ch-12

- addPeer:tXYB1vc5tzNaPQ3TAAFX,demo-ch-12-10.146.11.63 peers=46

- {"event":"User joined","roomId":"demo-ch-12","name":"user_270","ip":"10.146.1.169","peers":1,"routerId":"6e981d85-386b-4fab-b693-9c3fd733d228"}

#3: roomEventHandler:getRouterRtpCapabilities,roomId=demo-ch-12

#4: roomEventHandler:createWebRtcTransport,roomId=demo-ch-12

#5: roomEventHandler:getProducers,roomId=demo-ch-12

#6: roomEventHandler:consume,roomId=demo-ch-12

#7: roomEventHandler:consume,roomId=demo-ch-12

#8: roomEventHandler:connectTransport,roomId=demo-ch-12

Exit-room过程,仅一条消息:

#1: roomEventHandler:exitRoom,roomId=demo-ch-12

- removePeer:tXYB1vc5tzNaPQ3TAAFX,demo-ch-12-10.146.11.63 peers=45

- {"event":"exitRoom","reason":{}}

Mediasoup-client在获取到webrtc streaming data后,交给chrome等浏览器提供的api进行render渲染。这个还需要几十ms时间才能真正观看到视频。

在对node.js框架下的webrtc-server进行多进程MP/多线程MT改造前,先要对消息处理模块socket.io和webrtc流媒体处理模块mediasoup-worker进行介绍。

app = express()

httpsServer = httpolyglot.createServer(credentials, app)

httpsServer.listen(config.listenPort)

iowsSvr = sockio(httpsServer, {cors:true, cookie:{name:"iows",sameSite:"strict",maxAge:86400} })

httpServer是一个单进程,基于它的socket.io-event处理程序是多线程。

for (let i = 0; i < numWorkers; i++) {let worker = await mediasoup.createWorker({logLevel: config.mediasoup.worker.logLevel,logTags: config.mediasoup.worker.logTags,rtcMinPort: minPort,rtcMaxPort: maxPort})        //一个mediasoup-worker fork出一个子进程。}

首先尝试多线程MT方案,用node.js的worker_threads模块。

const { Worker, isMainThread, parentPort, workerData } = require('worker_threads')function iowsSvrListener (ioSvr) {ioSvr.on('connection', (socket) => {if (isMainThread){const wsWorker = new Worker(__filename, { workerData: socket })wsWorker.on('exit', () => {console.warn("wsWorker exit.")wsWorker.terminate()})wsWorker.on('message', (msg) => {console.debug("wsWorker recv:", msg)let socket = msg.socketsocket.onAny(async (eventName, args, cbFunc) => {await roomEventHandler(eventName, args, socket, cbFunc)})socket.on('disconnect', async (args) => {await roomEventHandler('disconnect', args, socket)})})}else {parentPort.postMessage(workerData)setInterval(() => {}, 60e3)}})}

上面这段代码,运行报错:

  - exitHandler:[object Promise],error=function noop() { } could not be cloned.

  >> socket is a complicated object which can not be passed to worker.

实际上,socket.io就是多线程框架,因此,我认为在多线程里面再去实现一个multi-threads是没有意义的。

下面再尝试一下多进程,用const cluster = require('cluster')

由于mediasoup-worker也是多进程,因此就成为socket.io server + mediasoup-worker的架构,这种框架,就大大增加SFU这种webrtc-server处理的复杂性。比如一个broadcaster在processor#1上进行直播,有一个room#1,一个观众从processor#2上来,他根本就无法join到room#1。这种情况就得要求processor#1上的mediasoup-worker pipe到processor#2上来才行。当然还有一个办法是processor#1上的socket.io forward msg to processor#2上的socket.io进行处理(内部转发),消息处理流程显得复杂了,多进程带来的效率提升恐怕也会被吃掉。

最终的结论就是,只能维持当前单进程socket.io server + 多进程mediasoup-worker的框架不变。如果想要进一步提升单台SFU-server的join速度,只能采用Go语言的协程(goroutine)机制了,但这能带来多大的性能提升呢?毕竟node.js的socket.io server性能也不差!而且,整体来说,mediasoup worker能够处理多大的视频流量,这受限于VPS服务器的bandwidth。

1 Gbps的网络,单进程mediasoup-worker就可以轻松处理(cpu load < 60%),可支持到200 peers(video + audio)。那么一个5Gbps的网络,满负荷运行需要5颗cpu,加上socket.io需要一颗cpu,那么6 core cpu的VPS就行了。

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

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

相关文章

明星录制祝福视频:传递温情与关怀的独特方式

在当今社交媒体和数字化时代&#xff0c;明星录制祝福视频已经成为一种新颖而独特的方式&#xff0c;用来表达温馨祝福、分享喜悦&#xff0c;或者为特殊的时刻增添一份特别的意义。无论是生日、结婚、毕业&#xff0c;还是节日、活动等&#xff0c;明星录制的祝福视频能够让人…

规避【虚拟专线技术】使用风险实现业务系统安全

本文为作者学习文章&#xff0c;按作者习惯写成&#xff0c;如有错误或需要追加内容请留言&#xff08;不喜勿喷&#xff09; 本文为追加文章&#xff0c;后期慢慢追加 一、技战法描述 VPN是利用Internet等公共网络基础设施&#xff0c;通过隧道加密通信技 术&#xff0c;为用…

QT实现TCP通信(服务器与客户端搭建)

一、TCP通信框架 二、QT中的服务器操作 创建一个QTcpServer类对象&#xff0c;该类对象就是一个服务器调用listen函数将该对象设置为被动监听状态&#xff0c;监听时&#xff0c;可以监听指定的ip地址&#xff0c;也可以监听所有主机地址&#xff0c;可以通过指定端口号&#x…

pdf用什么软件打开?介绍几种常用打开方法

pdf用什么软件打开&#xff1f;PDF是一种广泛使用的文件格式&#xff0c;由于其跨平台和易于共享的特点&#xff0c;它已成为许多人在日常工作和学习中使用的首选文件格式。但是&#xff0c;有时候我们可能会遇到一些问题&#xff0c;比如不知道用什么软件打开PDF文件&#xff…

【系统编程】线程池以及API接口简介

(꒪ꇴ꒪ )&#xff0c;Hello我是祐言QAQ我的博客主页&#xff1a;C/C语言&#xff0c;数据结构&#xff0c;Linux基础&#xff0c;ARM开发板&#xff0c;网络编程等领域UP&#x1f30d;快上&#x1f698;&#xff0c;一起学习&#xff0c;让我们成为一个强大的攻城狮&#xff0…

数据结构与算法-插入希尔归并

一&#xff1a;排序引入 我们通常从哪几个方面来分析一个排序算法&#xff1f; 1.时间效率&#xff1a;决定了算法运行多久&#xff0c;O&#xff08;1&#xff09; 2.空间复杂度&#xff1a; 3.比较次数&交换次数:排序肯定会牵涉到两个操作&#xff0c;一个比较是肯定的。…

《存储IO路径》专题:块设备层多队列blk-mq架构

我们想象一下&#xff0c;你是一个餐厅的厨师&#xff0c;你要准备很多不同的菜肴&#xff0c;而每种菜肴需要不同的食材和烹饪时间。如果每道菜都按照需要的顺序来准备&#xff0c;那么你的工作效率一定会非常低。为了提高效率&#xff0c;你会怎么做呢&#xff1f; 在linux架…

uni-app 之 v-on:click点击事件

uni-app 之 v-on:click点击事件 image.png <template><!-- vue2的<template>里必须要有一个盒子&#xff0c;不能有两个&#xff0c;这里的盒子就是 view--><view>--- v-on:click点击事件 ---<view v-on:click"onclick">{{title}}<…

Git 回顾小结

Git是一个免费开源&#xff0c;分布式的代码版本控制系统&#xff0c;版主开发团队维护代码 作用&#xff1a;记录代码内容&#xff0c;切换代码版本&#xff0c;多人开发时高校合并代码内容 Git常用命令 命令作用注意git -v查看Git版本git init初始化本地Git仓库git add 文件…

QTday5

一、客户端 二、服务器 三、配置图像处理环境 四、XMind思维导图

vscode新建vue3文件模板

输入快捷新建的名字 enter 确认后在文件中输入以下内容 {// Place your snippets for vue here. Each snippet is defined under a snippet name and has a prefix, body and// description. The prefix is what is used to trigger the snippet and the body will be expand…

无需租用云服务器:使用Linux本地搭建web服务并实现内网穿透发布公网访问的详细教程

文章目录 前言1. 本地搭建web站点2. 测试局域网访问3. 公开本地web网站3.1 安装cpolar内网穿透3.2 创建http隧道&#xff0c;指向本地80端口3.3 配置后台服务 4. 配置固定二级子域名5. 测试使用固定二级子域名访问本地web站点 前言 在web项目中,部署的web站点需要被外部访问,则…

前端自动化部署,Devops,CI/CD

DevOps 提到 Jenkins&#xff0c;想到的第一个概念就是 CI/CD 在这之前应该再了解一个概念。 DevOps Development 和 Operations 的组合&#xff0c;是一种方法论&#xff0c;并不特指某种技术或者工具。DevOps 是一种重视 Dev 开发人员和 Ops 运维人员之间沟通、协作的流程。…

Java on VS Code 8月更新|反编译器用户体验优化、新 Maven 项目工作流、代码高亮稳定性提升

作者&#xff1a;Nick Zhu 排版&#xff1a;Alan Wang 大家好&#xff0c;欢迎来到 Visual Studio Code for Java 的 8 月更新&#xff01;在这篇博客中&#xff0c;我们将为您提供有关反编译器支持的更多改进。此外&#xff0c;我们将展示如何创建没有原型的 Maven 项目以及一…

【C语言】字符函数,字符串函数,内存函数

大家好&#xff01;今天我们来学习C语言中的字符函数&#xff0c;字符串函数和内存函数。 目录 1. 字符函数 1.1 字符分类函数 1.2 字符转换函数 1.2.1 tolower&#xff08;将大写字母转化为小写字母&#xff09; 1.2.2 toupper&#xff08;将小写字母转化为大写字母&…

SpringMVC之入门

目录 1.SpringMVC工作流程 2.SpringMVC核心组件 2.1 DispatcherServlet 2.2 HandlerMapping 2.3 Handler 2.4 HandlerAdapter 2.5 ViewResolver 2.6 View 3.SpringMVC的入门 3.1 添加相关依赖 3.2 创建Spring-mvc.xml 3.3 配置web.xml 3.4 效果演示 4.静态资源处…

ios 运行ipa包 日志查看方式

方法一&#xff1a; 使用ideviceinstaller工具 # 安装ipa命令 brew install ideviceinstaller ideviceinstaller -i xxx.ipa# 查看运行日志 idevicesyslog# idevicesyslog 查找命令 idevicesyslog | grep test -A 3 -B 2 # 输出关键字所在行后3行&#xff0c;前2行) idevic…

GeoServe Web管理界面远程访问GeoServe Web管理界面的最佳工具

文章目录 前言1.安装GeoServer2. windows 安装 cpolar3. 创建公网访问地址4. 公网访问Geo Servcer服务5. 固定公网HTTP地址 前言 GeoServer是OGC Web服务器规范的J2EE实现&#xff0c;利用GeoServer可以方便地发布地图数据&#xff0c;允许用户对要素数据进行更新、删除、插入…

数据库-多表查询

概述&#xff1a; 介绍&#xff1a;多表查询&#xff1a;指从多张表中查询数据 笛卡儿积&#xff1a;笛卡儿积是指在数学中&#xff0c;两个集合&#xff08;A集合和B集合&#xff09;的所有组合情况&#xff08;在多表查询时&#xff0c;需要消除无效的笛卡儿积&#xff09; 分…

excel中的引用与查找函数篇1

1、COLUMN(reference)&#xff1a;返回与列号对应的数字 2、ROW(reference)&#xff1a;返回与行号对应的数字 参数reference表示引用/参考单元格&#xff0c;输入后引用单元格后colimn()和row()会返回这个单元格对应的列号和行号。若参数reference没有引用单元格&#xff0c;…