WebRTC是一种点对点的通讯机制,是在两个客户端建立了RTCPeerConnection连接后,进行通讯,可发送音视频流,也可以发送消息,如文字等等。
发送流的过程也不复杂,重点是建立连接的流程需要理解透彻。一般需要一个信令服务器做中转,相当于一个后台server,多个WebRTC客户端通过信令服务器做中转建立起点对点的通信。Server相当于中间人的角色。
假设分别有客户断A,客户端B,以及中间人Server
基本步骤如下
A登录 Server,登录成功,A在本地创建 yourConn
B登录Server,登录成功,B在本地创建 yourConn
A向B发起请求,一般需要先发送offer请求,其中需要带有B的用户名信息,将信令发送至Server
var callToUsername = callToUsernameInput.value;
if (callToUsername.length > 0) {
connectedUser = callToUsername;
// create an offer
yourConn.createOffer(function (offer) {
send({
type: "offer",
offer: offer
});
yourConn.setLocalDescription(offer);
}, function (error) {
alert("Error when creating an offer");
});
}
Server检测B是否在线,在线就转发offer请求到B
B客户端收到offer,回答A同意建立连接
function handleOffer(offer, name) {
connectedUser = name;
yourConn.setRemoteDescription(new RTCSessionDescription(offer));
//create an answer to an offer
yourConn.createAnswer(function (answer) {
yourConn.setLocalDescription(answer);
send({
type: "answer",
answer: answer
});
}, function (error) {
alert("Error when creating an answer");
});
};
这里很好理解,类似于打电话呼叫与应答。重点什么时候开始通话,是在用户之间处理另一个iceCandidate后,双方都彼此确定对方是自己的通信对象后,才开始建立通信。WebRTC中为候选人信息。
也就是,当客户端A接收到onicecandidate信号后,通过Server向客户端B发送候选请求,B记住A的候选人信息。
当客户端B收到onicecandidate信号后,通过Server向客户端A发送候选请求,A也记住B是候选人信息。
yourConn.onicecandidate = function (event) {
if (event.candidate) {
send({
type: "candidate",
candidate: event.candidate
});
}
};
}, function (error) {
console.log(error);
});
通俗点讲就是,彼此把自己当做候选人,告诉对方,双方交换候选人信息。完成这一步,就是完成了P2P的连接。
一开始看的时候不明白什么时候交换候选人信息。经过搜索查看文章,其实onicecandidate这个信号是在B应答后,A发起ICE Request后自动触发
所以整个过程相当于是这样:
A发起offer请求,同时告知B我是你候选人
B收到offer请求,后答复A,答复后,同时告知A我是的候选人。
双方交换候选人信息后,建立好连接。从Web角度看就是这么回事,如果深入到C++层面就非常复杂了,由于是内网两台机器进行点对点,所以要执行NAT穿透,通过中间信令服务器来查询对方ip。
至此,RTCSessionDescription 会自动完成发送音视频流的工作。
绑定收到流的回调,并对原始流进行显示。
在WebRTC中发送端和接收端,用的都是原始流信息。
底层自动完成了编解码的工作的。所以很适合点对点通信,同时也适合做多对多。
多对多通话中相当于任意两人之间都建立了一个P2P,也就是每个人和另外所有人都有一个RTCSessionDescription连接。
假设有N个人,那么每个人都会有N-1个RTCSessionDescription连接存在。
登陆成功后就创建了一个连接,如果是多对多,则需要在每当有人加进来的时候,其他的人都需要在创建一个链接,并与新加入的人建立ygie连接。
yourConn = new webkitRTCPeerConnection(configuration);
// setup stream listening
yourConn.addStream(stream);
//when a remote user adds stream to the peer connection, we display it
yourConn.onaddstream = function (e) {
remoteVideo.src = window.URL.createObjectURL(e.stream);
};
具体可参考这一系列的文章,WebRTC其实有多个版本的实现,也可以在不同版本间实现互联。
如Web端使用WebRTC,与C++桌面客户端互联。
其他讲解请参考:
OpenWebRTC- 跨平台的WebRTC客户端框架-面圈网