其他分享
首页 > 其他分享> > 基于socketio实现webrtc视频通话的流程

基于socketio实现webrtc视频通话的流程

作者:互联网

说明1:

对于socket.emit,我们要清楚,是给谁发送的,是调用这个方法的对象本身。
比如在客户端,这个socket对象应该是服务器,所以socket.emit,代表给服务器发送消息。
比如在服务器,这个socket对象应该是跟服务器连接的某个客户端socket对象,代表给这个客户端发动消息。
说明2:

nodejs中的callback代表异步回调,就是走完callback(data)这句,相当于开了一个子线程去执行,当前代码接着往下走。
流程:

按照发起方A往下走流程,调用requestServerCreateRoom方法,在这个方法里创建socket连接,将发起方A和接收方B的用户id传递给服务器,发送事件为“videoChat”。
服务器接收到videoChat事件,按照请求生成房间,并将房间号返回给发起方A。
发起方A收到房间号后,执行connectRoom方法;
进入connectRoom方法,进入addSocketHandles方法添加sockethandles.
添加的sockethandles用于一会接收服务器的事件消息,类似安卓添加点击事件一样,如果你想响应点击,就必须先注册 添加点击事件一个道理。加的sockethandles分别为:_peers、_ice_candidate、_new_peer、_remove_peer、_offer、_answer、cancelVideoChat;
添加完sockethandles之后进入joinRoom方法,通过socket给服务器发送__join事件,传递参数房间号。
服务器收到__join事件后,会根据请求的房间号,来遍历房间里的所有socketid,由于刚建立房间,现在房间是空的,即curRoom是空的,所以第一次没有触发_new_peer事件,代码接着往下走,
for循环执行完成后,会将当前连接socket对象即发起方A socket对象存入到房间里。
接着8,服务器会执行发送_peers事件,由于我们现在在服务器与发起方A的线程里,所以当前的socket对象是发起方,所以代表给发起方A发送_peers事件。由于connectionids现在长度为0,所以基本客户端的peers事件方法里没有做什么操作,只是把webrtc的本地流初始化。
接着第3条服务器在发给发起方A房间号后,并给接收方B发送videoChat事件。(与4--8并行执行)
接收方B收到videoChat事件,打开视频界面并将服务器传递过来的参数传递给视频界面。
视频界面打开判断是接收方还是发送方;由于现在是接收方B,所以是接收方,于是显示接听和拒绝按钮。
接收方B在视频界面点击同意按钮,进入connectRoom方法,进入addSocketHandles方法添加sockethandles。
添加的sockethandles用于一会接收服务器的事件消息,类似安卓添加点击事件一样,如果你想响应点击,就必须先注册 添加点击事件一个道理。加的sockethandles分别为:_peers、_ice_candidate、_new_peer、_remove_peer、_offer、_answer、cancelVideoChat;
添加完sockethandles之后进入joinRoom方法,通过socket给服务器发送__join事件,传递参数房间号。
服务器收到__join事件后,会根据请求的房间号,来遍历房间里的所有socketid,由于此时房间号rooms[房间号]里有一条信息,就是发起方A的socket对象,所以执行for循环的语句,向发起方A发起_new_peer事件,并将接收方B的socketid传递过去。
发起方A客户端接收_new_peer事件,创建Peer连接,添加本地流,并将peer放到peers集合中。peers集合存放了所有的连接。
发送完所有的_new_peer事件后,向接收方B发送_peers事件,传递参数当前房间除自己外的所有socket连接数组,还有自己的soeckedid;
接收方B客户端接收_peers事件后,跟传过来的所有socketid建立连接,添加连接流,生成offer,触发peer对象的回调方法onCreateSuccess,在这个方法里发送__offer事件给服务器。这里涉及到webrtc交互流程,参见。
服务器收到offer后,将该offer转发给对应的客户端(这里就是接收方B对应的客户端是发起方A)。
发起方A接收到offer后,加入一些参数后调用setRemoteDescription方法,调用成功后会回调onCreateSuccess方法,在 向这个方法里向服务器发送__answer,服务器接收到__answer后转发给接收方B。
接收方B接收到answer后,向stun服务器获取自己的ip地址,stun服务器返回ip后,会回调onIceCandidate方法,在这个 向方法里,向signal服务器(即上边经常提到的  服务器)发送__ice_candidate事件,服务器将事件转发给发起方A,
发起方A收到_ice_candidate事件后,向stun服务器查询自己的ip,返回成功后,回调onIceCandidate方法,这样整体建立一个p2p连接,开始视频。
总结:

以上是webrtc两个人视频通话的流程,我们可以总结一下几个关键点:

通过socketio的长连接,视频发起者在服务器创建一个房间;
创建房间成功后,发起者将自己的socket连接对象存于房间中,并初始化webrtc本地流;
服务器向接收者发送视频消息;
接收者收到视频消息后,初始化webrtc本地视频流,并与发起者建立peer连接;
接着进行webrtc信令交换流程;
建立p2p连接,开始视频聊天;
以两人通话流程为基础,我们可以实现三人通话;

通过socketio的长连接,视频发起者在服务器创建一个房间;
创建房间成功后,发起者将自己的socket连接对象存于房间中,并初始化webrtc本地流;
服务器向接收者1发送视频消息;
接收者1收到消息后,初始化webrtc本地视频流,并通过createPeerConnections(因为此时房间有前一人的socketid)发起者(发起者的new_peer调用)建立peer连接;
接着进行webrtc信令交换流程;
建立p2p连接,开始视频聊天;
服务器向接收者2发送视频消息;
接收者2收到消息后,初始化webrtc本地视频流,并通过createPeerConnections(因为此时房间有前两人的socketid)与发起者、接收者1(两者的new_peer调用)建立peer连接;
接着进行webrtc信令交换流程;
建立p2p连接,开始视频聊天;
按照上边理论3人和多人是一个道理的。over!

参考服务器socket调试截图:

参考视频通信流程log日志截图:

如何看emit发送是否成功呢?

页面JS:
……
socket.emit('nickname', '张三', function (data) {
           if (data) {
             console.log('Nickname set successfully');
           } 
         });
 服务端:
 ……
 socket.on('nickname', function (data, callback) {
    callback(data);
  });
参考文章:

webrtc信令交互流程
webrtc官网需要翻墙
Android之WebRTC介绍
转自https://blog.csdn.net/wzmde007/article/details/80006264

IT 哈 发布了39 篇原创文章 · 获赞 64 · 访问量 26万+ 私信 关注

标签:socket,socketio,房间,通话,发起方,peer,服务器,webrtc
来源: https://blog.csdn.net/qq_31967569/article/details/104123495