SRS4.0源码分析-创建RTMP协程 - 弦外之音

/ 0评 / 0

本文采用的 SRS 版本是 4.0-b8 , 下载地址:github


SRS4.0源码分析-RTMP入口》 讲解了 建立 RTMP 的入口是在 SrsServer::fd_to_resource() 函数,现在就来验证一下是不是真的在那里,断点调试很重要,有时候看代码会看错,现在就在 fd_to_resource() 函数打个断点,如下图:

果然,有 RTMP 请求来的时候,SRS 代码就会跑进去 new SrsRtmpConn() ,所以之前的分析没有错误。



本文 就来分析 SrsRtmpConn 类的逻辑。SrsRtmpConn 类的构造函数比较简单,如下:

注意上面第二个参数srs_netfd_t c ,这个是 ST 库的 fd,对原始的 tcp fd 封装了一下,推荐阅读《ST源码分析-server

SrsRtmpConn::SrsRtmpConn() 只有一个重点,就是创建了一个协程来处理这个 客户端的 TCP 链接。其他的代码我也简单过一下,如下:

_srs_context->set_id(_srs_context->generate_id());

_srs_context 是一个全局变量,主要是用来生成唯一ID,做日志跟踪的。这个变量跟上下文切换没有太大关系。请看后续文章《SRS4.0源码分析-_srs_context》

PS: SRS 里面 以 _ 开始的变量全都是全局变量。

skt = new SrsTcpConnection(c);

上面是创建一个 Tcp链接管理器,方便后面对这个 fd 进行读写。

clk = new SrsWallClock();

SrsWallClock 应该是一个时钟,请看后续文章《SRS4.0源码分析-SrsWallClock》

kbps = new SrsKbps(clk);

SrsKbps 是用来统计 IO 流量的,请看后续文章《SRS4.0源码分析-流量统计》


然后就是重点代码 new SrsSTCoroutine() ,从之前的文章可以知道多次出现 new SrsSTCoroutine() ,所以这个函数应该就是 SRS 创建协程的封装函数。这里讲解一下这个类的用法。请看下图:

第一个参数 nrtmp,这个是个字符串,标记是什么类型的协程。

第二个参数 h 就是重点,全部都是用 this,这是一种多态用法。这个 this 类要实现一个 cycle() 函数,然后协程运行的时候,就会跑到 cycle() 函数不断循环处理,在此刻 thisSrsRtmpConn

第三个参数 cid 是协程ID。可以理解为生成一个唯一标示。

所以,如果你要二次开发,你创建自己的协程的时候,需要新建一个类,实现一个 cycle() 函数,然后 丢进去 new SrsSTCoroutine() 函数就行。

这里虽然创建了协程,但是当前逻辑还没执行到 ST 库的阻塞函数,所以新创建的协程还未开始运行,代码还是会继续往下走。注意一点,用ST的协程,只有遇到阻塞函数才会开始切换上下文。


rtmp = new SrsRtmpServer(skt);

这个 SrsRtmpServer 类,不是监听端口,而是处理 RTMP握手逻辑的,可以理解为RTMP链接的管理器。这里提及一下,RTMP协议的实现大部分都在 srs_rtmp_stack.cpp 文件里面。

refer = new SrsRefer();

检测 refer,跟 http 的 refer 差不多,来源

bandwidth = new SrsBandwidth();

带宽检测,CDN,由于SRS刚开始的业务场景是 CDN,所以需要计算流量做带宽限制之类的。

security = new SrsSecurity();

这个是安全检测,允许哪些客户端可以进行推流拉流,具体请看《SRS4.0源码分析-鉴权原理》

wakable = NULL; 

这个 wakable 变量比较有趣,注意一下。暂时跳过

mw_sleep = SRS_PERF_MW_SLEEP;

这个是协程休眠阻塞,等收到了8个音视频包后,才会转发给播放器,达到合并写功能,能优化IO效率,具体请看《SRS为何能做到同类的三倍》,搜索 合并写入 即可。

_srs_config->subscribe(this);

上面这句代码应该是为了 reload 配置文件的时候,能有所响应,应该是注册一个 reload 的处理事件。

执行完上面的代码之后,SrsRtmpConn::SrsRtmpConn() 这个函数就退出了,只需要记得,里面创建了一个协程 函数 SrsRtmpConn::cycle()

到这里,SrsRtmpConn::SrsRtmpConn() 构造函数已经分析完毕。


具体在 TCP 的基础上建立 RTMP 链接的逻辑就会在 协程 SrsRtmpConn::cycle() 里面处理。下一篇文章就来 分析 SrsRtmpConn::cycle() 的逻辑。


由于笔者的水平有限, 加之编写的同时还要参与开发工作,文中难免会出现一些错误或者不准确的地方,恳请读者批评指正。如果读者有任何宝贵意见,可以加我微信 Loken1。QQ:2338195090。

发表回复

您的电子邮箱地址不会被公开。