前言:
而今朋友们对“srs架构”大约比较注重,兄弟们都需要剖析一些“srs架构”的相关资讯。那么小编同时在网上搜集了一些对于“srs架构””的相关知识,希望我们能喜欢,小伙伴们快快来学习一下吧!0.引言
在前面的文章已经讲述了怎么搭建srs流媒体服务器,演示了流媒体服务器成功的运行。读者,可以参考前面的文章,自行学习。文章列表如下:
手把手搭建流媒体服务器详细步骤
简述SRS流媒体服务器相关技术
手把手配置HLS流媒体服务器
流媒体服务器架构与应用分析
1.SRS框架认识
关于SRS框架的初步认识,如下图所示。首先是通过main,到run_master,run_master主要是负责监听以及svr->cycle主要做的工作。svr->listen可以监听多种协议,如rtmp,http等。这里就以监听rtmp协议为例子,listen_rtmp通过层层调用,一直到tcp的调用,最后会启动协程,也就是一个连接,会对应一个协程。SrsTcpListener::cycle()主要的功过就是读取协程是否结束,通过srs_accept检查是否有新的连接,用on_tcp_client(stfd)处理新的连接。在fd2conn()中,绑定了fd和连接,并选定了一个协程,也就是一个协程绑定一个连接。绑定连接后,就启动连接对应的协程,协程执行的主要工作是在一个cycle里面执行,就是这个SrsRtmpConn:service_cycle,调用stream_service_cycle(),继续发布和推流不同分支查找或创建一个source,这里就分出了2个分支,就是推流和拉流的动作。更为具体的工作,下面会有源码分析。
2.源码调试
gdb 调试srs源码
gdb ./objs/srs
调试界面如下:
设置参数:
set args -c ./conf/srs.conf
在某个函数下打断点:
b SrsTcpListener::listen()
界面如下:
项目运行起来,输入命令:
r
界面如下:
对应停在源码的地方,也就是前面打的端点处。源码如下:
这个时候,就可以观察调用栈,输入命令:
bt
经过以下一些函数,调用栈界面如下:
(1)main函数,对应目录srs/main/srs_main_server.cpp:192行。源码如下:
(2)do_main函数,对应目录srs/main/srs_main_server.cpp:184行。源码如下:
(3)run函数,对应目录srs/main/srs_main_server.cpp:409行。源码如下:
(4)run_master函数,对应目录srs/main/srs_main_server.cpp:469行。源码如下:
(5)SrsServer::listen函数,对应目录srs/app/srs_app_server.cpp:872行。源码如下:
(6)SrsServer::listen_rtmp函数,对应目录srs/app/srs_app_server.cpp:1258行。源码如下:
(7)SrsBufferListener::listen函数,对应目录srs/app/srs_app_server.cpp:155行。源码如下:
(8)SrsTcpListener::listen函数,对应目录srs/app/srs_app_listener.cpp:168行。源码如下:
3.源码分析
监听完后,需要有个循环accept,等待连接。
答案是每个监听,都是对应一个协程,每个客户端也是对应一个协程。
监听类型是很重要,创建连接的时候,需要创建不同的连接。监听类型如下:
监听和创建协程。
在trd->start():启动协程,如果协程要回调,可以通过this指针找到对象。启动协程后,就好会调用SrsSTCoroutine::cycle(),然后调用handler->cycle(),再调用SrsTcpListener::cycle()。
更加细致的流程如下:
调用cycle的源码,如下所示:
fd和connection的绑定,SrsServer::fd2conn,调用的是new SrsRtmpConn(this,stfd,ip),通过server服务(还可以管理其它事情)去管理所有连接。源码如下:
把所有的连接管理起来。
连接上之后,会启动协程。每个SrsRtmpConn都有1:1对应的协程,同时该连接,一定也对应一个cycle。只要某个类有start,那基本上意味着绑定了一个协程的循坏,肯定是调用该类的cycle去实现了。
服务端,具体的循环操作,源码如下:
设置窗口大小,带宽等。
真正循环体的实现。
SrsRtmpConn::stream_service_cycle(),一个直播对应一个source,一个推流,对应0-n个拉流。source的消费者,每个拉流都会绑定一个SrsConsumer。具体工作,
SrsSource对应客户端的consumers。
在这个循环里面,如果有播放或推流,它们对应的线程是不一样。
do_playing(source,consumer,&trd)和do_publishing(source,&trd)分别对应的协程是SrsQueueRecvThread trd(consumer,rtmp,xxx)和SrsPublishThread(),
4.总结
本篇文章结合源码调试,讲解了SRS流媒体框架的基本认识,学好基本框架,为后面的学习打好基础。
欢迎关注,转发,点赞,收藏,分享,评论区讨论。
后期关于项目的知识,会在微信公众号上更新,如果想要学习项目,可以关注微信公众号“记录世界 from antonio”
标签: #srs架构