1:客户端发起createtoken首先连接到nuve上,nuve本身就像一个网关一样,知道每一个已经存在的room在哪个erizo_controller上。erizo_controller 启动后会通过rpc通知nuve 并且插入数据库
2:createtoken的返回结果中包含了erizo_controller 的地址,下一步就可以根据该地址创建新房间或加入已有房间。
3:新版本licode 请求连接erizo_controller 时需要在url中拼接上token的返回结果中 host,tokenId signature字段,这个和以前版本有比较大出入,大概android是如下样子
String encodeHost = URLEncoder.encode(host, "UTF-8");
if (!host.startsWith("http://")) {
host = "https://" + host;
}
String encodeSig = URLEncoder.encode(signature, "UTF-8");
String encodeToken = URLEncoder.encode(tokenId, "UTF-8");
host = host + "?tokenId=" + encodeToken + "&signature=" + encodeSig + "&host=" + encodeHost;
4:get 请求发出去后licode 服务器会校验token,然后根据roomid 创建相应的client,该client监听续客户端发过来的消息。
5:用户发布stream时,licode erizo_controller会响应client的onPublish({ options, sdp }, callback) 函数,服务端会根据算法生成一个streamId作为该room中此用户的stream标识,最终该streamid和clientid会通过rpc调用到erizojs 服务中的addPublisher 方法,并在addPublisher 中会创建对应的client 对象,该client 会创建与客户端webrtc通信的实例webRTCConnetcion,该实例一边接收publisher 的上行数据,一边将数据分发给subscriber,中间的媒介为publisher对象,publisher对象会把mediastream和OneToManyProcessor进行接口连接
6:用户订阅流流程最终会调用到erizojs 服务中的addSubscriber ,该函数会根据streamid找到订阅的publisher对象,然后创建或获取client对象,然后创建一个和publisher相似的webRTCConnetcion对象和客户端传输数据,只不过subcriber的数据来自publisher,publisher的OneToManyProcessor 会把subscriobe 的connction 对象的meidastream 加入到列表中,当有数据到来的时候进行分发。
7:数据的传输的对象为DtlsTransport ,该对象会和客户端进行ice协商 和数据传输,webrtcconnection对象会监听该对象,当有数据到来时传递给webrtcconnection对象。
疑问和误区:
以前理解只要建立一次peerconnection就行,只用当publisher或者subscribe的时候 重新进行sdp协商即可,发现原来需要建立至少两个peerconnetion,一个peerconnection 用于publish,其他的用于subscribe,建立连接时的singlePC 参数说明订阅其他流时是否使用同一个peerconnection,但是没有解决为何不能用同一个peerconneciton ,可能是为了有更好的灵活性吧。