天天看点

crtmpserver 基本流程分析

最近在研究crtmpserver,这里记录下学习过程,首先我们先分析下基本流程。

1、初始化流程

InitNetworking---初始化网络

Initialize

Logger::Init()---初始化日志

lowerCase(extension) == "lua"---加载.lua后缀配置文件

LoadLuaFile

Normalize

NormalizeLogAppenders

初始化日志配置

NormalizeApplications

初始化监听配置

gRs.pConfigFile->ConfigLogAppenders()根据配置初始化

IOHandlerManager::Initialize()

初始化IO,读写队列清零

gRs.pConfigFile->ConfigModules()

加载动态库appselector.dll

ProtocolFactoryManager::RegisterProtocolFactory(gRs.pProtocolFactory) 加载默认支持的协议集合

gRs.pConfigFile->ConfigAcceptors()

根据IP和端口开启监听器

gRs.pConfigFile->ConfigInstances()

配置多实例,win下不支持

gRs.pConfigFile->ConfigApplications()

将监听器与实例绑定

installQuitSignal

设置程序退出机制

Run

IOHandlerManager::Pulse()

对socket资源进行轮询,查询是否有需要进行读写的socket操作

2、接收客户端的连接请求之connect

Pulse()

FD_ISSET(MAP_VAL(i)->GetInboundFd(), &_readFdsCopy)

MAP_VAL(i)->OnEvent(_currentEvent)

TCPAcceptor::Accept()

进入accept进行连接的创建

BaseProtocol *pProtocol = ProtocolFactoryManager::CreateProtocolChain

为连接创建对应配置的协议,比如tcp && rtmp,或者udp && rtcp==

TCPCarrier *pTCPCarrier = new TCPCarrier(fd)

为连接创建一个tcp交互对象,并将其和刚创建的协议对象绑定,创建时构造函数中就注册了读请求

TCPCarrier::OnEvent(select_event &event)

进入读分支读取数据,根据对应的协议分析读取的数据依据结果填充_outputBuffer发送缓冲区,并设置发送信号TCPCarrier::SignalOutputData()--->ENABLE_WRITE_DATA,通知Pulse轮询socket状态需要发送数据,然后再次进入TCPCarrier::OnEvent(select_event &event)写分支进行真正的数据发送操作

RTMP消息类型为:RM_INVOKE_FUNCTION_CONNECT

3、接收客户端的发布流之Publish

这一段属于rtmp协议交互的部分

RM_INVOKE_FUNCTION_RELEASESTREAM

这里没有获得stream名称,发送名称请求

RM_INVOKE_FUNCTION_FCPUBLISH

这里获得stream名称

RM_INVOKE_FUNCTION_CREATESTREAM

ProcessInvokeCreateStream

pFrom->CreateNeutralStream(id) == NULL

RTMPStream *pStream = new RTMPStream

这里创建一个rtmpstream流控制对象  RTMPStream ---> BaseStream

RM_INVOKE_FUNCTION_PUBLISH

ProcessInvokePublish

GetApplication()->GetAllowDuplicateInboundNetworkStreams()这里判断是否存在同名情况

InNetRTMPStream *pInNetRTMPStream = pFrom->CreateINS(VH_CI(request) 创建network inbound stream

GetApplication()->GetStreamsManager()->GetWaitingSubscribers 查询是否有请求这路流的连接并绑定pBaseOutStream->Link(pInNetRTMPStream);

pInNetRTMPStream->SendOnStatusStreamPublished()

发送准备接收流请求

BaseOutFileStream *pOutFileStream = CreateOutFileStream(pFrom, meta, appending);另外,如果需要录像,这里创建文件流连接

4、接收客户端请求实时流

RM_INVOKE_FUNCTION_PLAY

ProcessInvokePlay

pFrom->CloseStream(VH_SI(request), true)

关闭该连接之前请求的流

TryLinkToLiveStream(pFrom, VH_SI(request), streamName, linked)

将该连接绑定

FOR_MAP(inboundStreams, uint32_t, BaseStream *, i)

通过streamName查询找到流输入

BaseOutNetRTMPStream * pBaseOutNetRTMPStream = pFrom->CreateONS(streamId, 先创建流输出

pBaseInNetStream->Link(pBaseOutNetRTMPStream)

然后将流输出绑定至流输入