简介 全称是: Web browser Real Time Communication
适用于网页间音视频实时通信,点对点数据共享,QQ、腾讯视频已有应用 优势 1.方便。对于用户来说,在WebRTC出现之前想要进行实时通信就需要安装插件和客户端,但是对于很多用户来说,插件的下载、软件的安装和更新这些操作是复杂而且容易出现问题的,现在WebRTC技术内置于浏览器中,用户不需要使用任何插件或者软件就能通过浏览器来实现实时通信。 1.传输质量难以保证,比如跨地区、跨运营商、低带宽、高丢包、P2P连接率、呼叫成功率。 WebRTC内部结构简化图 WebRTC架构图(截图来自官网https:///) WebRTC核心技术点,简要概括为三部分 下文详细介绍WebRTC核心API和信令服务器部分相关学习资料推荐,点击下方链接免费报名,先码住不迷路~】 音视频免费学习地址: 【免费分享】音视频学习资料包、大厂面试题、技术视频和学习路线图,资料包括(C/C++,Linux,FFmpeg webRTC rtmp hls rtsp ffplay srs 等等)有需要的可以点击788280672加群免费领取~ WebRTC 核心API详解运用RTCPeerConnection和RTCDataChannel两个核心API,能够实现任意数据的点对点交换,官网Demo如下: 该Demo不需要servers,因为呼叫方(发送数据)和呼叫应答方(接收数据)在同一页面上,这样能够清晰的了解RTCPeerConnection API的原理,页面上的RTCPeerConnection对象可以直接交换数据和消息,而无需使用信令服务器。
Demo 代码分析以Demo为例,分析Web P2P创建、通信、传输数据等流程,具体分析API中各个关键属性、方法、事件的含义和标准操作姿势 function createConnection() { sendButton.disabled = true; megsToSend.disabled = true; var servers = null; bytesToSend = Math.round(megsToSend.value) * 1024 * 1024; // 创建连接,servers可以传入一些描述信息,由于这个demo不需要验证连接信息,在同一个页面上可以直接连接,该参数传null即可 localConnection = localConnection = new RTCPeerConnection(servers); //打印log trace('Created local peer connection object localConnection'); var dataChannelParams = { ordered: false }; if (orderedCheckbox.checked) { dataChannelParams.ordered = true; } //创建数据通道 语法:dataChannel = RTCPeerConnection .createDataChannel(label [,options ]);,lable:通道的名称;optins:是个可选参数,传入数据通道配置参数,有很多参数可选,例子中的ordered:true表示有序模式,false即为无序模式,还有其他参数maxPacketLifeTime 、maxRetransmits等等 sendChannel = localConnection.createDataChannel('sendDataChannel', dataChannelParams); sendChannel.binaryType = 'arraybuffer'; trace('Created send data channel'); //绑定onopen、onclose、onicecandidate(当RTCPeerConnection被createPeerConnection()成功创建时触发,回调会返回待连接端的配置信息) sendChannel.onopen = onSendChannelStateChange; sendChannel.onclose = onSendChannelStateChange; localConnection.onicecandidate = function (e) { onIceCandidate(localConnection, e); }; //创建呼叫实例 localConnection.createOffer().then( gotDescription1, onCreateSessionDescriptionError ); //创建远端接收连接实例 remoteConnection = remoteConnection = new RTCPeerConnection(servers); trace('Created remote peer connection object remoteConnection'); remoteConnection.onicecandidate = function (e) { onIceCandidate(remoteConnection, e); }; //当一个RTC数据通道已被远端调用createDataChannel()添加到连接中时触发 remoteConnection.ondatachannel = receiveChannelCallback;}function receiveChannelCallback(event) { trace('Receive Channel Callback'); receiveChannel = event.channel; receiveChannel.binaryType = 'arraybuffer'; //接收到数据时触发 receiveChannel.onmessage = onReceiveMessageCallback; receivedSize = 0;}function onReceiveMessageCallback(event) { receivedSize += event.data.length; receiveProgress.value = receivedSize; if (receivedSize === bytesToSend) { closeDataChannels(); sendButton.disabled = false; megsToSend.disabled = false; }}function onSendChannelStateChange() { var readyState = sendChannel.readyState; trace('Send channel state is: ' + readyState); if (readyState === 'open') { sendGeneratedData(); }}function sendGeneratedData() { sendProgress.max = bytesToSend; receiveProgress.max = sendProgress.max; sendProgress.value = 0; receiveProgress.value = 0; var chunkSize = 16384; var stringToSendRepeatedly = randomAsciiString(chunkSize); var bufferFullThreshold = 5 * chunkSize; var usePolling = true; if (typeof sendChannel.bufferedAmountLowThreshold === 'number') { trace('Using the bufferedamountlow event for flow control'); usePolling = false; // 缓冲区大小限值 bufferFullThreshold = chunkSize / 2; // 缓冲区大小控制 sendChannel.bufferedAmountLowThreshold = bufferFullThreshold; } // bufferedamountlow 事件处理 var listener = function () { sendChannel.removeEventListener('bufferedamountlow', listener); sendAllData(); }; var sendAllData = function () { // 把一堆数据排队进行处理,在数据通道被填满时停止,这里不建议每次发送后设置Timeout,这样会降低吞吐量 while (sendProgress.value < sendProgress.max) { if (sendChannel.bufferedAmount > bufferFullThreshold) { if (usePolling) { setTimeout(sendAllData, 250); } else { sendChannel.addEventListener('bufferedamountlow', listener); } return; } sendProgress.value += chunkSize; // send方法发送数据,RTCDataChannel的语法跟WebSocket语法非常相似,都有message事件和sand方法 sendChannel.send(stringToSendRepeatedly); } }; setTimeout(sendAllData, 0);} WebRTC核心API兼容性 MediaStream and getUserMedia
RTCPeerConnection
RTCDataChannel
信令服务器 信令就是协调通讯的过程,为了建立一个webRTC的通讯过程,客户端需要交换如下信息:
下面是NodeJS创建信令服务器的源码:
利用WebRTC相关技术有很多可以创新的点,比如业界已有创业团队在做Web P2P,核心技术就是WebRTC + DASH协议,共享空闲资源,基于此可以做雾CDN,节点都在用户侧,去中心化,这里还是有很多挖掘空间的。 参考资料 |
|