一、交互结构图
二、总体结构:
1. 大部分数据结构都直接使用的glib的库提供的;
2. 将网络层做了一个封装和业务部分用回调方法来解偶;
3. 和第三方服务用网络TCP/UDP连接方式用简单自定义文本协议来交互;
4. 可以将相关的状态同步给redis外部缓存, 供其它外界的分析调用;
5. 采用内核相关模块来进行媒体的交换, 提高应用性能。
三、流程分析
1. main方法一路下去, 先进行options方法的调用, 主要是使用glib提供的库方法简单的对命令行参数进行解析并校验判断;
2. 接着init_everything()方法, 日志库, ssl库, 信号等的初始化, 时钟的获取, 系统资源限制的设置,ICE模块等等全局的初始化;
callmaster_new(ctx->p)创建一个会话管理器, 用来管理所有会话, 其中定义了一个定时器及会话表, 并定义了对info及stream进行协议匹配及分析的正则式;
4. 初始会话管理器的配置及参数, callmaster_config mc 填充, 主要有内核表句柄kernelfd, 全局队列实例GQueue interfaces, 临时端口的区间, 支持的最大session数量, 等;
5. 创建和第三方指令服务的信令交互的TCP监听服务, 使用配置:LISTEN_TCP=127.0.0.1:2222, 指令有:request, lookup, delete, build|version|controls|quit|status, 主要分为三类其包体的结构也不一样, 第一类是创建及关联peers对, 一类是删除节点, 一类是供第三方服务来查看媒体代理服务的总体状态及运行情况及本session的状态, 创建监听端口, 并设置消息接收处理的回调方式后加入全局的poller事件监听器中去, 等待和处理消息;
6. 创建和第三方指令服务的信令交互的UDP监听服务, 使用配置:LISTEN_UDP=127.0.0.1:2222, 填充协议解析正则式, 同样也分为三种协议格式, 一类是U/L(update/lookup)主要用来处理offer/answer的相关建立会话场景的处理信令, 一类是D/Q(delete/query)主要是用来处理会话的拆除及相关参数状态的查询, 一类是V(version)版本等相关信息的查询;
7. 创建和第三方指令服务的信令交互的UDP NG临听服务, 使用配置:LISTEN_NG=127.0.0.1:2223; 可以交互修改SDP信息同UDP的监听方式;
8. 不管第三方服务以上述哪一种连接方式接入, 最终都是为了把会话的场景给建立起来, 当offer信令到达时, 使用各种参数将Aside的session给填充起来, 当answer信令到达时, 从缓存中查出Aside的相关参数, 和Bside的相关属性关联起来monologue_offer_answer()方法中完成, 然后初使化出A, Bside的接收RTP数据包的服务端口在__get_endpoint_map方法中的__stream_fd_new方法中完成各边数据包接收服务端口的开启,, 并设置媒体数据处理回调stream_fd_readable, 在其中进行媒体的交换.