使用Swoole协程实现 WebRTC 信令服务器

使用Swoole协程实现 WebRTC 信令服务器

一、什么是WebRTC

WebRTC技术是激烈的开放的Web战争中一大突破-Brendan Eich, inventor of JavaScript。

简单来说,WebRTC 是一个音视频处理+及时通讯的开源库。在实时通信中,音视频的采集和处理是一个很复杂的过程。比如音视频流的编解码、降噪和回声消除等。由Google发起开源,其中包含视频音频采集,编解码,数据传输,音视频展示等功能,我们可以通过技术快速地构建出一个音视频通讯应用。虽然其名为WebRTC,但是实际上它不只是支持Web之间的音视频通讯,还支持Android以及IOS端,此外由于该项目是开源的,我们也可以通过编译C++代码,从而达到全平台的互通。

WebRTC的架构图为:

(图片来自网络)

我们可以看到模块化和分层的设计,我们文章的目的是演示浏览器端对端的连接流程,焦点是服务端信令服务器的实现方式,但需要提前介绍一些WebRTC的基本概念和连接流程。

二、基础概念

流和轨

  • Track 轨道,可以理解每一路音频或视频,为一个轨,互不相交,类比火车轨道。

  • MediaStream 媒体流,每个媒体流中包含若干轨道,可以将音频轨,视频轨打包在一起。

三、几个关键类

  • MediaStream 媒体流类,MeidiaStream用于将多个MediaStreamTrack对象打包到一起。一个MediaStream可包含audio track 与video track,并且可以添加或者删除。

  • RTCPeerConnection 连接类,包含非常多重要功能,屏蔽复杂技术细节,便于应用层使用,包括但不限于连接管理,P2P类型检测,NAT穿透,中转等。

  • RTCDataChannel 非音视频数据传输类,这个类在我们的例子中没有涉及到。可以简单理解为将媒体流信息或者数据信息塞到连接中,进行传输。

四、端对端连接流程

两个不同网络环境浏览器,要实现点对点的实时音视频对话,需要处理那些问题?

媒体协商

双方需要知道对方支持的媒体格式,SDP(Session Description Protocol)是一种会话描述协议,视频通讯的双方必须先交换SDP信息,才能进一步互相通信。

网络协商

双方要了解对方的网络情况,尝试寻求一个可以互相通讯的链路,其中有寻路选择,如果确实没办法建立点对点链路,会使用中继服务器来进行转发。如果是内网,或者大部分NAT网络环境下,是可以建立端到端连接。在解决网络打通问题时候,有几个概念。

  • STUN(Session Traversal Utilities for NAT,NAT会话穿越应用程序)是一种网络协议,它允许位于NAT后的客户端找出自己的公网地址,查出自己位于哪种类型的NAT之后以及NAT在公网的端口映射信息。这些信息被用来在两端创建UDP连接通信。

  • TURN (Traversal Using Relays around NAT),如果客户端在NAT之后, 那么在一些网络情景下,有可能建立点对点的通讯连接,这时就需要公网的服务器作为一个中继, 对数据进行转发。

学习过程中,STUN和TURN服务器我们可使用coturn开源项目来搭建。

数据交换服务-信令服务器

WebRTC实现并没有规定信令服务器的实现方式和相关协议,这给了业务方技术选型极大的灵活。我们今天就是使用PHP+Swoole协程实现一个简单信令服务器。下面是一个端到端连接的流程图,整个核心流程逻辑都在图里面。

(图片来自网络)

五、使用Swoole实现信令服务器

客户端代码模拟​​​​​​​

<body><div style="display: block">    <button class="btn" onclick="start()">连接</button>    <button class="btn" onclick="leave()">离开</button></div><div>    <div class="videos">        <h1>Local</h1>        <video id="localVideo" autoplay></video>    </div>    <div class="videos">        <h1>Remote</h1>        <video id="remoteVideo" autoplay></video>    </div></div><script src="assets/js/adapter.js"></script><script type="text/javascript">    const ws_config = '<?= $signaling_server ?>';    const localVideo = document.getElementById('localVideo');    const remoteVideo = document.getElementById('remoteVideo');    const configuration = {
          iceServers: [{
              urls: '<?= $stun_server ?>'        }]    };
    let room_id = getQueryVariable('room_id');    if (room_id == '' || room_id == null) {
          room_id = Math.random().toString(36).slice(-8);        location.href = '?room_id=' + room_id;    }    let subject = 'room-' + room_id;//当前主题    let answer = 0;    let ws = null;    let pc, localStream;
    function getMediaStream(stream) {
          localVideo.srcObject = localStream;        localStream = stream;    }
    function start() {
          ws = new WebSocket(ws_config);        ws.onopen = function (e) {
              subscribe(subject);            if (!navigator.mediaDevices || !navigator.mediaDevices.getUserMedia) {
                  console.error('the getUserMedia is not supported!');  
转载请说明出处内容投诉
CSS教程_站长资源网 » 使用Swoole协程实现 WebRTC 信令服务器

发表评论

欢迎 访客 发表评论

一个令你着迷的主题!

查看演示 官网购买