github:https://github.com/bigonelby/webrtcUml/tree/master/latest
这个图介绍了webrtc中数据上报的架构
主要由三部分构成:搜集信息;构建上报;上报回调
首先是搜集信息。核心类是RTCStatsCollector,从命名上可以看出非常贴切,就是Stats的搜集者。有个通用的设计就是A依赖B,B亦依赖A的问题,这种情况下,往往是A has-a B,B has-a interface of A。这里的PeerConnection和RTCStatsCollector就是这样。RTCStatsCollector是PeerConnection的小弟,为其服务,搜集信息。但是小弟也需要大哥的资源,于是抽象出了PeerConnectionInternal,被RTCStatsCollector持有。那么RTCStatsCollector需要什么信息呢?就是GetTransceiversInternal。也就是他需要知道所有的RtpTransceiver,这是所有信息的搜集起点。有了PeerConnectionInternal,RTCStatsCollector就可以得到这个关键信息,这为以后的搜集工作奠定基础
真正的搜集工作要开始了,RTCStatsCollector构建了结构体用来记录搜集的信息,结构体就是RtpTransceiverStatsInfo。他的关键成员RtpTransceiver是从PeerConnectionInternal中得到的。有了RtpTransceiver,就有了所有的信息,这实在是一张王牌!RtpTransceiver掌管了channel_!即ChannelInterface,这个channel_就是VideoChannel / VoiceChannel / DataChannel 这种最顶级的Channel了。通过ChannelInterface的media_channel(),就可以得到对应的媒体通道。我们以视频为例,media_channel()返回的即为WebrtcVideoChannel。而WebrtcVideoChannel有一个关键的方法,就是GetStats,这个方法可以得到底层的状态信息,即返回的是VideoMediaInfo,这个才是关键!后面会发现上报所需要的所有信息,都是由这个VideoMediaInfo生成的!不过目前,我们只是把信息保存在结构体里即可,RtpTransceiverStatsInfo中有一个重要的成员,即TrackMediaInfoMap,我们将搜集到的信息统一保存在这个结构体里,以便后面的使用
现在我们已经有了所有需要上报的信息,接下来的工作就是构建上报了。即RTCStatsReport。这个集合里是由一个个RTCStats构成的,并通过AddStats方法将这些RTCStats加到自己的类中。我们以RTCOutboundRTPStreamStats为例,这是一个RTCStats,我们需要构建好后通过AddStats方法加到RTCStatsReport中。构建的过程不复杂,因为关键的信息都是从VideoSenderInfo中来的,我们这里的工作不过就是移花接木,将已经搜集好的信息,赋值到RTCOutboundRTPStreamStats中即可。这里有个关键,类的成员类型是RTCStatsMember,而不是普通的int或string之类的,这样做有两个好处,其一,就是通过RTCStatsMember的name()以及ValueToJson()迅速完成json化转换;其二,可以将不同的基本类型统一为RTCStatsMember,这样方便RTCStats的管理,通过Members()方法,就可以拿到所有的成员。因而可以很方便的将RTCStatsReport,Json化!这个是核心!
最后就可以将上报返回给上层了。上层本来在调用PeerConnection的GetStats方法,就传递了回调函数RTCStatsCollectorCallback,RTCStatsCollector首先将这个回调封装在RequestInfo中,然后在构建完上报RTCStatsReport后,通过RequestInfo的call_back_就可以将最终的上报返回给上层了!