【MediaSoup---源码篇】(三)Transport
概述
RTC::Transport是mediasoup中的一个重要概念,它用于在mediasoup与客户端之间传输实时音视频数据。
Transport继承着众多的类,主要用于Transport的整体感知
class Transport : public RTC::Producer::Listener,public RTC::Consumer::Listener,public RTC::DataProducer::Listener,public RTC::DataConsumer::Listener,public RTC::SctpAssociation::Listener,public RTC::TransportCongestionControlClient::Listener,public RTC::TransportCongestionControlServer::Listener,public Channel::ChannelSocket::RequestHandler,public PayloadChannel::PayloadChannelSocket::RequestHandler,public PayloadChannel::PayloadChannelSocket::NotificationHandler,
分析Transport的创建流程
在Router层会根据类型来进入分支创建transport,以PlainTransport为例
case Channel::ChannelRequest::MethodId::ROUTER_CREATE_PLAIN_TRANSPORT:{std::string transportId;//从上层获取到transport的ID// This may throwSetNewTransportIdFromData(request->data, transportId);auto* plainTransport =new RTC::PlainTransport(this->shared, transportId, this, request->data);// Insert into the map.绑定ID与transport的映射this->mapTransports[transportId] = plainTransport;MS_DEBUG_DEV("PlainTransport created [transportId:%s]", transportId.c_str());json data = json::object();plainTransport->FillJson(data);request->Accept(data);break;}
在构造函数中,创建了socket,并且绑定了通道消息回调
PlainTransport::PlainTransport(RTC::Shared* shared, const std::string& id, RTC::Transport::Listener* listener, json& data): RTC::Transport::Transport(shared, id, listener, data){MS_TRACE();auto jsonListenIpIt = data.find("listenIp");if (jsonListenIpIt == data.end())MS_THROW_TYPE_ERROR("missing listenIp");else if (!jsonListenIpIt->is_object())MS_THROW_TYPE_ERROR("wrong listenIp (not an object)");auto jsonIpIt = jsonListenIpIt->find("ip");if (jsonIpIt == jsonListenIpIt->end())MS_THROW_TYPE_ERROR("missing listenIp.ip");else if (!jsonIpIt->is_string())MS_THROW_TYPE_ERROR("wrong listenIp.ip (not an string)");//获得内网IPthis->listenIp.ip.assign(jsonIpIt->get<std::string>());// This may throw.Utils::IP::NormalizeIp(this->listenIp.ip);auto jsonAnnouncedIpIt = jsonListenIpIt->find("announcedIp");if (jsonAnnouncedIpIt != jsonListenIpIt->end()){if (!jsonAnnouncedIpIt->is_string())MS_THROW_TYPE_ERROR("wrong listenIp.announcedIp (not an string");//获得外网IPthis->listenIp.announcedIp.assign(jsonAnnouncedIpIt->get<std::string>());}//获取端口uint16_t port{ 0 };auto jsonPortIt = data.find("port");//判断端口是否合法if (jsonPortIt != data.end()){if (!(jsonPortIt->is_number() && Utils::Json::IsPositiveInteger(*jsonPortIt)))MS_THROW_TYPE_ERROR("wrong port (not a positive number)");port = jsonPortIt->get<uint16_t>();}auto jsonRtcpMuxIt = data.find("rtcpMux");if (jsonRtcpMuxIt != data.end()){if (!jsonRtcpMuxIt->is_boolean())MS_THROW_TYPE_ERROR("wrong rtcpMux (not a boolean)");this->rtcpMux = jsonRtcpMuxIt->get<bool>();}auto jsonComediaIt = data.find("comedia");if (jsonComediaIt != data.end()){if (!jsonComediaIt->is_boolean())MS_THROW_TYPE_ERROR("wrong comedia (not a boolean)");this->comedia = jsonComediaIt->get<bool>();}auto jsonEnableSrtpIt = data.find("enableSrtp");// clang-format offif (jsonEnableSrtpIt != data.end() &&jsonEnableSrtpIt->is_boolean() &&jsonEnableSrtpIt->get<bool>())// clang-format on{auto jsonSrtpCryptoSuiteIt = data.find("srtpCryptoSuite");if (jsonSrtpCryptoSuiteIt == data.end() || !jsonSrtpCryptoSuiteIt->is_string())MS_THROW_TYPE_ERROR("missing srtpCryptoSuite)");// Ensure it's a crypto suite supported by us.auto it =PlainTransport::string2SrtpCryptoSuite.find(jsonSrtpCryptoSuiteIt->get<std::string>());if (it == PlainTransport::string2SrtpCryptoSuite.end())MS_THROW_TYPE_ERROR("invalid/unsupported srtpCryptoSuite");// NOTE: The SRTP crypto suite may change later on connect().this->srtpCryptoSuite = it->second;switch (this->srtpCryptoSuite){case RTC::SrtpSession::CryptoSuite::AEAD_AES_256_GCM:{this->srtpMasterLength = SrtpAesGcm256MasterLength;break;}case RTC::SrtpSession::CryptoSuite::AEAD_AES_128_GCM:{this->srtpMasterLength = SrtpAesGcm128MasterLength;break;}case RTC::SrtpSession::CryptoSuite::AES_CM_128_HMAC_SHA1_80:case RTC::SrtpSession::CryptoSuite::AES_CM_128_HMAC_SHA1_32:{this->srtpMasterLength = SrtpMasterLength;break;}default:{MS_ABORT("unknown SRTP crypto suite");}}this->srtpKey = Utils::Crypto::GetRandomString(this->srtpMasterLength);this->srtpKeyBase64 = Utils::String::Base64Encode(this->srtpKey);//进行base64编码}try{// This may throw. 通过 listenIp, port 创建 UdpSocketif (port != 0)this->udpSocket = new RTC::UdpSocket(this, this->listenIp.ip, port);elsethis->udpSocket = new RTC::UdpSocket(this, this->listenIp.ip);if (!this->rtcpMux){// This may throw.this->rtcpUdpSocket = new RTC::UdpSocket(this, this->listenIp.ip);}// NOTE: This may throw.this->shared->channelMessageRegistrator->RegisterHandler(this->id,/*channelRequestHandler*/ this,/*payloadChannelRequestHandler*/ this,/*payloadChannelNotificationHandler*/ this);}catch (const MediaSoupError& error){delete this->udpSocket;this->udpSocket = nullptr;delete this->rtcpUdpSocket;this->rtcpUdpSocket = nullptr;throw;}}
相关文章:
【MediaSoup---源码篇】(三)Transport
概述 RTC::Transport是mediasoup中的一个重要概念,它用于在mediasoup与客户端之间传输实时音视频数据。 Transport继承着众多的类,主要用于Transport的整体感知 class Transport : public RTC::Producer::Listener,public RTC::Consumer::Listener,publ…...
爱分析《商业智能最佳实践案例》
近日,国内知名数字化市场研究咨询机构爱分析发布《2023爱分析商业智能最佳实践案例》,此评选活动面向落地商业智能的各行企业和商业智能厂商,以第三方专业视角深入调研,评选出具有参考价值的创新案例。永达汽车集团与数聚股份合作…...
golang:context
context作用 goroutine的退出机制 多个goroutine都是平行的被调度的,多个goroutine如何协调工作涉及通信、同步、通知和退出 通信:goroutine之间的通信同步chan通道 同步:不带缓冲的chan提供了一个天然的同步等待机制。通过WaitGroup也可以…...
探讨代理IP与Socks5代理在跨界电商中的网络安全应用
在数字化时代,跨界电商已经成为了商业世界中的一大趋势。然而,跨越国界的电商活动也伴随着网络安全挑战。本文将讨论如何利用代理IP和Socks5代理技术来提高跨界电商中的网络安全,同时也探讨了与游戏相关的爬虫应用。 1. 代理IP和Socks5代理的…...
Guava Cache介绍-面试用
一、Guava Cache简介 1、简介 Guava Cache是本地缓存,数据读写都在一个进程内,相对于分布式缓存redis,不需要网络传输的过程,访问速度很快,同时也受到 JVM 内存的制约,无法在数据量较多的场景下使用。 基…...
ARM 汇编指令作业(求公约数、for循环实现1-100之间和、从SVC模式切换到user模式简单写法)
1、求两个数最大公约数 .text .globl _start_start:mov r0, #9mov r1, #15 Loop: 循环cmp r0,r1 比较r0和r1的大小beq stop 当r0和r1相等时,跳到stop标签subhi r0,r0,r1 r0-r1>0 时,证明r0>r1,将r0-r1的值赋给r0&…...
Go - 【字符串,数组,哈希表】常用操作
一. 字符串 字符串长度: s : "hello" l : len(s) fmt.Println(l) // 输出 5遍历字符串: s : "hello" for i, c : range s {fmt.Printf("%d:%c ", i, c) } // 输出:0:h 1:e 2:l 3:l 4:ofor i : 0; i < le…...
vue 普通组件的 局部注册
vue 普通组件的 注册 11 Vue2_3入门到实战-配套资料\01-随堂代码素材\day03\素材\00-准备代码\小兔鲜首页静态页\src...
医疗虚拟仿真和虚拟现实有什么区别?哪个更好?
随着我们在仿真教育中越来越多地使用新技术,区分虚拟模式的类型很重要。虚拟仿真是一个统称,用来概括术语来描述各种基于仿真的体验,从基于屏幕的平台到沉浸式虚拟现实。然而,各虚拟平台在保真度、沉浸感和临场感的水平上有很大差…...
【.net core】yisha框架使用nginx代理swagger接口无法访问问题
后端代码配置 #在StartUp.cs文件中Configure方法中增加以下代码 app.UseSwagger(c >{//代理路径访问c.PreSerializeFilters.Add((doc, item) >{//根据代理服务器提供的协议、地址和路由,生成api文档服务地址doc.Servers new List<OpenApiServer>{ new…...
uniapp录音功能和音频播放功能制作
录音功能 在 UniApp 中,你可以使用 uni.getRecorderManager() 方法来创建一个录音管理器实例,从而实现录音功能。 以下是一个示例,演示了如何在 UniApp 中使用 uni.getRecorderManager() 实现录音功能: // 在需要录音的页面或组…...
服务器数据恢复-LINUX操作系统下各文件系统误删除/格式化数据的恢复方案
服务器数据恢复环境: 基于EXT2/EXT3/EXT4/Reiserfs/Xfs文件系统的Linux操作系统。 服务器故障: LINUX操作系统下误删除/格式化数据。 服务器数据恢复过程: 1、首先会检测服务器是否存在硬件故障,如果检测出硬件故障,交…...
python/C++二分查找库函数(lower_bound() 、upper_bound,bisect_left,bisect_right)
二分查找是一种经典的搜索算法,广泛应用于有序数据集中。它允许在大型数据集中高效地查找目标元素,减少了搜索的时间复杂度。本文将介绍在 C 和 Python 中内置的二分查找函数,让二分查找变得更加容易。 c lower_bound() 、upper_bound 定义…...
爬虫 — App 爬虫(二)
目录 一、Appium介绍二、node.js 安装三、Java 的 SDK 安装以及配置1、安装步骤2、配置环境变量 四、安卓环境的配置1、配置环境变量 五、Appium 安装1、安装2、打开 APP3、使用 六、Appium 使用1、定位数据(方法一,不常用)2、定位数据&#…...
汽车电子相关术语
SOA SOA(Service-Oriented Architecture,面向服务的架构)是一种在计算机环境中设计、开发、部署和管理离散模型的方法。是由Garnter1996年提出的概念,将应用程序的不同功能单元(称为服务)进行拆分…...
Python 找出最大数
"""在输入的三个数中找出最大知识点:1、条件嵌套语句if/else2.字符串分割函数split()3、列表元素索引4、数据类型转换举一反三:1、如何控制只能输入三个数,否则重新输入2、如何避免输入无效字母"""# 定义一个变…...
Spring Security 用了那么久,你对它有整体把控吗?
文章目录 1.Servlet Filter:守门人的角色2.DelegatingFilterProxy:桥接 Servlet 和 Spring 的神器3.FilterChainProxy:Spring Security 过滤器链的管家3.SecurityFilterChain:Security 过滤器的串绳4.Spring Security 中的过滤器机…...
vue+minio实现文件上传操作
vueminio实现文件上传操作 minio文件上传vueminio实现文件上传操作 minio文件上传 minio文件上传有两种方法: 第一种是通过ak,sk,调用minio的sdk putObject进行文件上传;该方法支持go,java,js等各种语言&…...
使用JavaScript实现无限滚动的方法
前言 在网页设计中,无限滚动是一种常见的交互方式,用户可持续地加载更多内容而无需刷新页面,提高用户体验。本文将介绍如何运用JavaScript实现无限滚动的效果,使网页能够自动加载更多数据,减轻用户加载新页的负担&…...
html学习综合案例1
<!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>个人简介</title> </head> <body>…...
基于eBPF的系统调用监控:原理、部署与性能调优实战
1. 项目概述:一个“无人值守”的系统调用监控器最近在折腾系统性能分析和安全监控,发现了一个挺有意思的开源项目:syscalldev/nohuman。这个名字直译过来是“无人”,听起来有点神秘,但其实它的核心功能非常直接——一个…...
Cadence-OS深度解析:Uber Cadence增强发行版的生产实践指南
1. 项目概述与核心价值最近在梳理工作流自动化工具时,又翻出了paulophl94/cadence-os这个项目。它不是一个全新的轮子,而是基于 Uber 开源的 Cadence 工作流引擎,进行深度定制和增强的一个发行版。如果你正在为微服务架构下的复杂业务流程编排…...
从零构建高频无线传输系统:调幅技术实战解析
1. 调幅无线传输系统入门指南 第一次接触调幅无线传输系统时,我也被各种专业术语搞得一头雾水。简单来说,调幅(AM)就是通过改变载波信号的幅度来传递信息的技术。想象一下快递员送包裹:载波就像快递车,而我们要发送的信息就是包裹…...
C++ 时间戳实战:从GetTickCount64到std::chrono的跨平台精度选择
1. 为什么我们需要精确的时间戳? 在开发高性能应用时,时间戳的精度往往决定了程序的可靠性。想象一下,你在开发一个在线游戏服务器,玩家A声称自己先击中了玩家B,但服务器记录的两次命中时间差只有几毫秒。如果使用秒级…...
如何免费获取全球50+图书馆古籍资源:BookGet数字古籍下载完整指南
如何免费获取全球50图书馆古籍资源:BookGet数字古籍下载完整指南 【免费下载链接】bookget bookget 数字古籍图书下载工具。 项目地址: https://gitcode.com/gh_mirrors/bo/bookget 还在为寻找古籍文献而烦恼吗?想要从哈佛、国会图书馆等全球知名…...
Go语言匿名函数如何写_Go语言匿名函数和闭包教程【对比】
Go匿名函数写作func(参数)返回类型{函数体},需完整声明;闭包是匿名函数引用外层局部变量并逃逸出作用域时形成的行为结果,捕获变量引用而非值。Go 里匿名函数怎么写,直接上手就用Go 的匿名函数就是没名字的函数字面量,…...
点云成像三维焊缝识别与机器人跟踪【附代码】
✨ 长期致力于点云成像、焊缝识别定位、机器人、点云拼接、焊缝轨迹跟踪研究工作,擅长数据搜集与处理、建模仿真、程序编写、仿真设计。 ✅ 专业定制毕设、代码 ✅如需沟通交流,点击《获取方式》 (1)基于圆柱体拟合与ICP拼接的点云…...
VLSI时代下74系列离散逻辑芯片的现代应用与设计实践
1. 从“胶水逻辑”到“系统粘合剂”:离散逻辑芯片的现代生存法则 在今天的数字电路设计领域,提起“7400系列”或者“74HC04”,很多年轻工程师的第一反应可能是博物馆里的古董,或者教科书上的历史章节。主流叙事已经被SoC、FPGA和高…...
AI-Trader性能优化:提升AI代理交易速度的10个终极技巧
AI-Trader性能优化:提升AI代理交易速度的10个终极技巧 【免费下载链接】AI-Trader "AI-Trader: 100% Fully-Automated Agent-Native Trading" 项目地址: https://gitcode.com/GitHub_Trending/aitrad/AI-Trader AI-Trader作为100%全自动化的AI代理…...
CANN/asc-devkit SPM缓冲区写入API
WriteSpmBuffer 【免费下载链接】asc-devkit 本项目是CANN 推出的昇腾AI处理器专用的算子程序开发语言,原生支持C和C标准规范,主要由类库和语言扩展层构成,提供多层级API,满足多维场景算子开发诉求。 项目地址: https://gitcode…...
