今天我们来介绍直播客户端的实现,首先我们来看一下直播客户端的一个状态机,客户端与服务器直接通过信令的一个交互之后自然而然的形成一个状态机,最开始的时候状态机是处于初始化状态的,这时候当用户发送了一个join到服务端之后服务端会给它回一个joined消息,所以在客户端收到joined的消息之后就变成了加入状态,这个时候用户是可以离开房间的,当他离开的时候它又回到了初始化或者是离开状态,这个大家都比较好理解;

当一个用户处于joined的状态的时候,另外一个用户又进来了,这个时候它就变成了joined_conn状态,也就是说加入并且可以与对方进行通话的状态,这对于房间里已经存在的这个人,它的状态就发生变化了,这个变化就是通过otherjoin消息通知的,当他收到otherjoin的时候它就改变这个状态,对于后加入这个人,它还是处于joined这个状态,因为它自己并没有收到otherjoin这个消息,所以房间这两个人其实是两个不同的状态,第一个人是先加入的是joiner_conn状态 ,那么后加入的是join状态,那对于join_conn这个状态的用户它也可离开,当他离开的时候它也处于初始化或者离开状态,这也是没有任何问题的。

实现1V1音视频实时互动直播系统 十二、第六节 WebRTC客户端状态机及处理逻辑_信令

那如果离开的时候它会发送一个bye给这个现在还在房间中这个用户,那这个用户收到bye这个消息的时候它变成joined_unbind,它虽然已经在这个房间内,但是由于另外一个用户已经走了,所以他们直接进行通讯的这个连接已经不需要了,那这个时候需要释放这个连接,所以要将peerconnection这个中的相应通道全部进行解绑,所以它就处于joined_unbind这个状态,那 如果这个用户这个时候处于joined_unbind状态,这时候又有一个用户进来了,所以新进来这个用户又变成了joined_conn状态,而另外进来这个用户它又是变成了这个join的状态,那如果它处于join_conn这个状态的时候,就是说他们两直接可以进行通讯了,那么这时候如果有一个用户也就是说后加入这个用户它离开了,当它离开了,它就回到这个joined_unbind状态,

 

那处于joined_unbind状态那它也可以离开,那这个时候是房间里一个人都没有了,那都处于初始化和离开状态,经过这样一个状态机之后呢,我们客户端与服务器之间就可以进行交互了,那这是它在整个房间中各个用户状态的变化的一个状态机。

实现1V1音视频实时互动直播系统 十二、第六节 WebRTC客户端状态机及处理逻辑_数据_02

在下来我们看一下客户端的流程图, 

最开始的时候首先获取这个音视频数据,但如果不能获取到,那就直接失败了,比如说这次通讯肯定不能完成了,但是如果能获取到的时候,那他就要这个拿到数据之后呢,再与这个信令进行连接,然后注册相关的这个处理函数,也就是我们接收服务端的这个函数,包括加入成功,这个另外一个用户加入房间满离开,还有对方给你说的bye,这五个消息,注册网这个消息之后呢,当你信令来的时候就会通过这个注册的消息触发一个事件,OK,那再发送加入房间消息在这一块儿呢,实际就是触发了这个相应的事件,也就是说我们注册完之后,服务器端发送消息的时候会触发各个不同的一个事件处理,首先呢,如果说有一个用户加入的房间,那么他首先要设置状态,说我现在已经处于加入的状态,这时候它要创建并绑定媒体流PeerConnection,

创建一个我们最终通讯的通道,并且将媒体流绑定,这是用户加入的情况,如果这时候房间里面没有任何人,他也要进行这个绑定,就说先让他预备好。另外呢,如果说有另外一个用户加入了,那他要判断他现在是这个现在的状态,那现在如果他是一个未绑定状态,那这个时候呢,他要创建PeerConnection,可能就要跟对方进行通讯,并且绑定这个他本地的媒体流到这个PeerConnection后面才能进入相应通讯,那如果不是这种状态对吧,他是一个join状态,那这时候它就变成了这个join_conn,说明在这之前它已经绑定过了,它绑定了之后所以就不需要绑定,这时候他只要改变状态,变成了join_conn状态,然后变成join_conn状态之后就开始形成,然后收集这个candidate进行连接性检测,最终传输,这是第二个分之;

那么第三个分支呢。就当这个房间满了,一会用户来了发现房间满了,这时候让他设成房间满的状态,但关闭他所创建的这些资源PeerConnection,最后的是关闭本地的流,因为最开始的时候是一启动就获取音视频设备,而且从音视频设备中获取用,那么这时候你需要将这些资源释放,这是最开始的这三个,重复得来的这个消息。

实现1V1音视频实时互动直播系统 十二、第六节 WebRTC客户端状态机及处理逻辑_信令_03

另外还有消息呢,就是还有这个leave消息,就当离开的时候把它分成两个,一个是当我发送本身自己想离开的时候,收到服务器端确认已离开的消息的时候,那这时候它变成了leave状态,已经初始状态,这时候关闭连接就好了,OK。但如果他是主动的发起方,他发起的时候其实他要做一部分工作,他就说叫我现在已经有了这个PeerConnection,只要关闭掉,然后呢,关闭这个音视频设备,也就是媒体流。再一个呢,就是跟对方说byebye的时候,当你收到对方说byebye的时候,那这时候你就变成了join_unbind状态,同样也要关闭对应的peerconnection,那在关闭之后另外用户再加入的时候,让你收到otherjoin这个消息的时候又会重新创建PeerConnection并进行绑定。这就是客户端的基本流程,就是它分成了两部分,第一部分呢是跟加入相关的,一是成功,另外是接触到对应的用户加入,还有什么房间加入已满?第二个是跟离开相关的,一个是这个自己发送离开这个逻辑,然后呢,刚才已经处理完了退出来,你要变更状态,还一个呢,收到其他人的离开的时候,你要做相应的状态的变化以及相应的逻辑处理,OK,这就是客户端的一个基本流程,那接下来呢,我们再回顾一下之前所讲的端对端连接的基本流程。

实现1V1音视频实时互动直播系统 十二、第六节 WebRTC客户端状态机及处理逻辑_信令_04

首先是A与B进行通讯,首先进行信令的连接,连接完了之后整个信令就打通了,对吧,那么这个时候他要创建链接,并且将重新音视频设备加入到这个PeerConnection里去,做一次绑定,绑定之后就开始整个的媒体协商,创建Offer,setLocalDescription,那这个时候呢,会触发收集candidate,创建完Offer之后,通过信令然后转发给这B端呢,B端呢,B端也要做相应的创建连接,设置remote description,创建Answer一系列操作,最终也要出发去收集这个candidate,通过信令再回来,交给A端,那么A端最终设置一个setRemoteDescription,这样整个协商部分在这块就完了,完了之后呢,就开始收集这个candidate,进行这个candidate的交换,我们信令中都有专门的这个message,就是做中转的,端对端的中转,将双方的candidate进行交互,添加到自己的列表里面进行连通性检测,整个中间这块儿就是对于整个候选者的这个数据检测连通性,OK,那么这完了之后,整个数据通道就打通了,就开始传数据,当A向B发送数据的时候,B收到一个事件,叫onAddStream或者onTrack,说到这个事件的时候,将底层的远端数据直接添加到本地的这个video标签里去,就能将远端的数据反映出来音频视频,以上呢,就是我们客户端的整体的状态机的变换,主要流程以及分离到连接的一个基本过程,OK!