WebRTC学习笔记(1) 前端Web纯原生JS实现P2P数据通道连接

基于https://www.bilibili.com/video/BV1Wi4y1N74y

标题纯原生JS的意思就是,不含任何后端代码,服务器搭建等操作,用最纯粹的方式实现

主要原理

关于WebRTC的原理,我的白话理解就是,两个客户端,创建自己的地址信息(SDP),然后通过某种方式两者交换一下记录对方的地址, 就能直接建立端到端的通信通道了。

由于通信过程中不用经过服务器中转,所以对服务器的负荷压力小,但是在多端交互时一个客户端要将一份数据复制多份同时传输,客户端的带宽可能不够,总之是有好有坏的。但是鉴于其不错的延迟和未来ipv6的支持,我感觉这个技术还有很多潜力。

在实际使用中,一般由一个端发送出offer,通过服务器(一般用websocket)送给另一个端,后者返回一个answer给发送端,offer和answer就是两端的SDP,互相记录一下就可以开始通信了。
发送端和接收端是平等的,一般可以进入房间的人给每一个人发一个offer,或是每进一个人,房间中每个人给他发一份offer

JS代码原理演示

发送端创建自己的SDP:
所谓iceCandidate就只是说明具有SDP了而已,当各个端将自己的SDP设置成自己的本地地址setLocalDescription后,就是成为一个iceCandidate

下面的代码有很多匿名式的写法,大概理解一下,其实格式差不多照抄就行

//source
const senderP = new RTCPeerConnection();


//打开一个数据通道,并设置打开和接收到消息的处理函数
const dc = senderP .createDataChannel("channel");
dc.onmessage = e => console.log("Got a message:" + e.data);
dc.onopen = e => console.log("Connection opened!")


//设置当成为ICEcandidate后,打印自己的地址
senderP.onicecandidate = e => console.log("New Ice Candidate! My SDP : " + JSON.stringify(senderP.localDescription)) 


//当createOffer后,将offer设置到本地Description中,此时自己就成为了一个iceCandidate,便触发地址打印函数
senderP.createOffer().then(o => senderP.setLocalDescription(o) ).then( a => console.log("set successfully!"))

在这里插入图片描述
如图,此时就打印出来了一个SDP,也就是发送端要发送出去的offer,
现在是发送端的本地地址,要设置为接收端的远程地址

我们把它记录下来,打开一个新的窗口,创建一个新的端。这个端用来接收

//首先把发送端送来的offer记录一下
let offer = {xxxxxxxxxxxxxx}


//destination
const receiveP = new RTCPeerConnection();


当出现ICEcandidate后,打印自己的地址
receiveP.onicecandidate = e => console.log("New Ice Candidate! My SDP : " + JSON.stringify(receiveP.localDescription))


//当接收到数据通道后,记录到本地。并设置打开和关闭的消息处理函数
receiveP.ondatachannel = e => {
    receiveP.dc = e.channel; 
    receiveP.dc.onmessage = e => console.log("new message from client!" + e.data); 
    receiveP.dc.onopen = e => console.log("Connection Opened!")
}


//当接收到对方的offer信息后,设置到本地连接的RemoteDescription中
receiveP.setRemoteDescription(offer).then(a => console.log("offer set!"))


//后创建应答,并将应答设定为本地Description中,此时自己也就成为了一个iceCandidate,获取到自己的地址
receiveP.createAnswer().then (a => receiveP.setLocalDescription(a)).then(a => console.log("answer created"))

在这里插入图片描述
最后只需要将这个SDP(接收端创建的answer)发回去,设置为发送端的远程地址
这样两者的本地、远程地址就都有了

senderP.setRemoteDescription(answer)

可以直接从datachannel中发送信息
在这里插入图片描述
可以配置媒体流直接发送,不过以后再说,关于这里的P2P连接还有别的要做

STUN的NAT穿透

上面的方法只适用于没有NAT网关的情况下,也就是两台设备都拥有自己的公网IP,或者是同处于一个局域网下才可以实现连接

但是我们一般两台电脑都是在各自家里的路由器的管理下的,也就是对外只有NAT享受公网IP的快乐
所以需要通过STUN方案获取公网IP和局域网IP,

其原理是本机既然无法问NAT自己的地址是什么,那就向一个外部的服务器发送一个数据包,外部服务器就会帮忙解析出自己的地址并发回去,此时的SDP将同时具有公网IP和局域网IP的定位能力

TURN的保底连接

此外STUN也有可能失败,比如咱中国错综复杂的运营商、wifi/4g网络差异,有可能STUN定位失败,这是要通过TURN方案强行建立连接

其原理和普通服务器转发基本一样,带来巨大的服务器负载压力,所以还蛮难受的从对技术的情感上来看

STUN/TURN配置方法

配置方法是在创建RTCPeerConnection时导入配置参数,构建对象时就会自动使用STUN/TURN
STUN服务器只是用来定位,有许多免费可用的,TURN服务器要求负载能力比较高,购买挺贵的应该,不过我是自己搭了一个用用就行

let configuration = {
    'iceServers':[{
        'url':'stun:stun.voipbuster.com:3478'
    },
    {
        'url':'turn:49.235.xxx.xx',
        username:'test',credential:'test'
    }]
}
const peer = new RTCPeerConnection(configuration);
  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
WebRTCWeb Real-Time Communication)是一个开放标准的实时通信技术,可以在浏览器之间直接立音视频通信,无需任插件或额外的软件。要WebRTC实现视频聊天,你可以WebRTC提供的Web API。 以下是一些实现视频聊天的基本步骤: 1. 获取用户媒体设备:使用`getUserMedia`方法获取用户的音视频流。这个方法会请求用户授权访问摄像头和麦克风。 2. 建立Peer Connection:使用`RTCPeerConnection`对象来建立两个浏览器之间的连接。这个对象负责建立和管理音视频传输通道。 3. 信令传输:为了建立Peer Connection,你需要一个信令服务器来传递连接所需的信息。你可以使用WebSocket或者其他实时通信方式来传输信令。 4. 连接建立和ICE候选者收集:一旦Peer Connection建立,浏览器会开始收集ICE(Interactive Connectivity Establishment)候选者,这些候选者用于在两个浏览器之间建立点对点连接。 5. 建立数据通道:如果你需要在视频聊天中传输其他数据(如文本消息),你可以使用`RTCDataChannel`对象来创建一个可靠的双向数据通道。 6. 媒体流传输:通过Peer Connection的音视频传输通道,你可以将用户的音视频流进行传输和呈现。 注意,以上只是基本的步骤概述,实际的实现可能还涉及到一些其他的细节和处理逻辑。你可以参考WebRTC官方文档以及一些开源的WebRTC库和示例代码来更详细地了解和实现视频聊天功能。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值