• 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和port开启监听器
    gRs.pConfigFile->ConfigInstances() 配置多实例,win下不支持
    gRs.pConfigFile->ConfigApplications() 将监听器与实例绑定
    installQuitSignal 设置程序退出机制


    Run
    IOHandlerManager::Pulse() 对socket资源进行轮询,查询是否有须要进行读写的socket操作






    2、接收client的连接请求之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交互对象,并将其和刚创建的协议对象绑定,创建时构造函数中就注冊了读请求


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


    RTMP消息类型为:RM_INVOKE_FUNCTION_CONNECT


    3、接收client的公布流之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、接收client请求实时流
    这一段属于rtmp协议交互的部分


    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) 然后将流输出绑定至流输入







  • 相关阅读:
    【推荐】com.alibaba方式xml转json,能将xml的所有属性方法,全部转化为json
    关于使用JAXB读取xml文档转换为java对象报错:类的两个属性具有相同名称com.sun.xml.internal.bind.v2.runtime.IllegalAnnotationsExc...
    java正则,将<a或者</a,尖括号后面的字母改成大写
    javaben转xml
    三次握手四次挥手
    RPC接口测试(六)RPC协议解析(重要!重要!重要!)
    os.popen(cmd) 与 os.system(cmd) 的区别
    jmeter测试webSocket接口
    Ubuntu20.04 体验和美化
    API可视化管理平台YApi
  • 原文地址:https://www.cnblogs.com/hrhguanli/p/3833916.html
Copyright © 2020-2023  润新知