前端开发您现在的位置是:首页 > 博客日志 > 前端开发

【p2p】RTCPeerConnection协议理解

<a href='mailto:'>微wx笑</a>的头像微wx笑 2022-11-05前端开发 3 0关键字: RTCPeerConnection  p2p  

一、SDPSDP全称是Session Description Protocol,翻译过来就是描述会话的协议。主要用于两个会话实体之间的媒体协商。SDP协议结构SDP描述由许多文本行组成,文本行的格式为<类

在这里插入图片描述0sI无知

一、SDP

SDP全称是Session Description Protocol,翻译过来就是描述会话的协议。
主要用于两个会话实体之间的媒体协商。
SDP协议结构
SDP描述由许多文本行组成,
文本行的格式为<类型>=<值>,
<类型>是一个字母
<值>是结构化的文本串
SDP的 文本信息包括:
会话名称和意图描述
v = (协议版本)
o = (所有者/创建者和会话标识符
s = (会话名称)
i = * (会话信息)
u = * (URI 描述)
e = * (Email 地址)
p = * (电话号码)
c = * (连接信息 ― 如果包含在所有媒体中,则不需要该字段)
b = * (带宽信息)
时间描述
t = (会话活动时间)
r = * (0或多次重复次数)
媒体描述
m = (媒体名称和传输地址)
i = * (媒体标题)
c = * (连接信息 — 如果包含在会话层则该字段可选)
b = * (带宽信息)
k = * (加密密钥)
a = * (0 个或多个会话属性行)0sI无知

二、提议/应答(offer/answer)模型

1.提议
提议者产生一个 SDP 消息来描述它所期望的会话,这构成了一个提议(offer)。
提议中主要包括提议者想使用的媒体流和codecs集,以及提议者用于接收媒体的IP地址和端口。
2.应答
提议被传送到应答者,应答者可能会接受,也可能会拒绝这个提议。如果接收,应答者根据收到的提议和自身的能力产生一个SDP消息来描述它所能接受的会话,这称为应答(answer),应答中针对提议中的每个媒体流有一个匹配流,指示该媒体流是否被接受,同时伴随着要使用的codecs 和应答者希望用于接收媒体的 IP 地址和端口。
3.在提议/应答的操作中需遵守以下原则:
在任何时候,任何一方都可能产生一个新的提议来更新会话。然而,如果它收到了一个提议还没有应答或拒绝,则不能产生新的提议。
提议/应答交换是不可分的,如果应答被拒绝,会话恢复到提议前的状态。
提议 (和应答) 必须是RFC 2327 中所定义的有效SDP消息。尽管 SDP 规范允许将多个会话描述串接在一起形成一个大的 SDP 消息,但是在提议/应答模型中使用的SDP消息必须恰好包含一个会话描述。
在提议/应答模型中交换假定存在一个高层协议 (比如SIP),它能够完成SDP消息的交换,并能维持某种上下文关系,将一个提议及其应答,和创建和更新同一个会话的多个提议/应答对关联起来。0sI无知

三、STUN 和 TURN

https://blog.csdn.net/u011077027/article/details/1004960990sI无知

STUN(Session Traversal Utilities for NAT,NAT会话穿越应用程序):
(1)客户端找出自己的公网地址
(2)查出自己位于哪种类型的NAT之后
(3)以及NAT为某一个本地端口所绑定的Internet端端口。
这些信息被用来在两个同时处于 NAT路由器之后的主机之间建立UDP通信。
这个过程俗称NAT打洞或NAT穿越。0sI无知

TURN(Traversal Using Relays around NAT,转发方式穿越NAT)是STUN的一个拓展,主要添加了转发功能。
如果终端在NAT之后, 那么在特定的情景下,有可能使得终端无法和其对等端(peer)进行直接的通信,这时就需要公网的服务器作为一个中继, 对来往的数据进行转发。
客户端通过发送Allocate请求给STUN服务器,从而让STUN服务器为A用户开启一个relay端口,可以看做是A的公网代理端口,TURN服务器就像代理服务器一样转发访问A用户的数据。
在STUN分配公网IP失败后,可以通过TURN服务器请求公网IP地址作为中继地址。
这种方式的带宽由服务器端承担,在多人视频聊天的时候,本地带宽压力较小。0sI无知

四、ICEcandidate

ICEcandidate 用来表示远端通信的 protocol、ip、port
其中最主要的ICEcandidate的类型,分为下列三种类型:
● host 类型:本机内网,内网P2P连接
● srflx 类型:本机NAT映射后的外网,非对称型NAT网络环境,外网P2P连接
● relay 类型:一般是对称性NAT网络,需要走TURN中继服务器,无法建立P2P连接
其实 ICE 就是上面所讲的获取各种类型 Candidate 的过程,也就是:在本机收集所有的 host 类型的 Candidate,通过 STUN 协议收集 srflx 类型的 Candidate,使用 TURN 协议收集 relay 类型的 Candidate。0sI无知

如果想确定自己浏览器里的webrtc客户端建立的是什么类型,可以通过chrome://webrtc-internals/查看0sI无知

//示例:
	candidate: 
		{ 
			candidate: 'a=candidate:138613430 1 udp 2122260223 10.10.10.232 61421 typ host generation 0 ufrag /9uN network-id 1 network-cost 10',
     		sdpMid: '0',
     		sdpMLineIndex: 0 
     	} 
//说明:
a:			会话属性行
candidate:	表明收到ICE候选者
138613430:	标志和区分来自同一个stun的不同的候选者,ID标识
1:			ICE的组ID
udp:		协议类型
2122260223:优先级priority
10.10.10.232:公网IP
61421:		公网IP转发的端口号
typ:		标识符,标识后面字段的属性类型是type
host:		本地接口获取到的candidate,该字段还可以是(”host”, “srflx”, “prflx”, “relay”)
generation 0:	代号,表明当前是第几代的候选
ufrag /9uN:		ICE分配的用户名标识 
network-id 1:	网卡标识 
network-cost 10:

参考https://www.jianshu.com/p/1b00d73c93e7
host:本地接口获取到的candidate
srflx:NAT网关在公网侧的IP地址,通过STUN或者是TURN收集(server reflexive candidate)
prflx:可以在ICE的后续阶段中获取到(peer reflexive candidate)
relay:TURN服务器的公网转发地址,通过TURN收集(relayed candidate)
当TURN服务器启用时,两种地址都是从TURN服务器上获取到的。如果只有STUN服务器启用,那么只有server reflexive candidate可以从服务器获取到0sI无知

var localConnection = new RTCPeerConnection(null, null);//创建一个RTCPeerConnection对象.对于SCTP,可靠且有序的交付默认为true。
var sendChannel = localConnection.createDataChannel('sendDataChannel', null);
localConnection.onicecandidate = event=> {//网络候选变得可用时,调用此函数。
    if (event.candidate) {
        localConnection.addIceCandidate(
            event.candidate
        ).then(
            ()=>console.log('AddIceCandidate1 success.',event.candidate),
            (e)=>console.log('Failed to add Ice Candidate: ',e)
        )
    }
}

var remoteConnection = new RTCPeerConnection(null, null);
remoteConnection.onicecandidate = event =>{
    if (event.candidate) {
        localConnection.addIceCandidate(
            event.candidate
        ).then(
            ()=>console.log('AddIceCandidate success.'),
            (e)=>console.log('Failed to add Ice Candidate: ',e)
        );
    }
};
remoteConnection.ondatachannel = event=>{
    var receiveChannel = event.channel;
    receiveChannel.onmessage = (event)=>console.log("receive:",event.data);
};

localConnection.createOffer().then(
    desc =>{
        localConnection.setLocalDescription(desc);//desc.sdp
        remoteConnection.setRemoteDescription(desc);
        remoteConnection.createAnswer().then(
            desc0 =>{
                remoteConnection.setLocalDescription(desc0);//desc0.sdp
                localConnection.setRemoteDescription(desc0);
            },
            e=>console.log(e)
        )
    },
    e=>console.log(e)
)

sendChannel.onopen=(event)=>{
    console.log("sendChannel.onopen",event)
    sendChannel.send(123);
}

五、SDP与candidate

candidate描述一个页面。SDP描述两个页面之间的连接方式。
先协商SDP,然后再交换candidate
协商完成后会自动调用onicecandidate
RTCIceCandidate0sI无知

address: "100.67.7.193"
candidate: "candidate:100934627 1 udp 2122260223 100.67.7.193 49849 typ host generation 0 ufrag mIc8 network-id 1 network-cost 10"
component: "rtp"
foundation: "100934627"
port: 49849
priority: 2122260223
protocol: "udp"
relatedAddress: null
relatedPort: null
sdpMLineIndex: 0
sdpMid: "0"
tcpType: null
type: "host"
usernameFragment: "mIc8"

RTCSessionDescription.sdp:0sI无知

v=0
o=- 4475725184886384564 2 IN IP4 127.0.0.1
s=-
t=0 0
a=group:BUNDLE 0
a=extmap-allow-mixed\r\na=msid-semantic: WMS
m=application 9 UDP/DTLS/SCTP webrtc-datachannel
c=IN IP4 0.0.0.0\r\na=ice-ufrag:mIc8
a=ice-pwd:Jbywz1ybw7WpxV0Jcu1HPEO2
a=ice-options:trickle
a=fingerprint:sha-256 3C:89:81:1B:C4:43:39:64:7D:33:07:FA:D3:92:5F:6A:E4:8D:B2:86:A6:18:E1:A5:E7:29:90:AE:AC:31:30:65
a=setup:actpass
a=mid:0
a=sctp-port:5000
a=max-message-size:262144
```![在这里插入图片描述](https://img-blog.csdnimg.cn/64d96e29fc554b45b812321d64bd3fce.png?x-oss-process=image/watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBAQmlnIE9yYW5nZS4uLg==,size_14,color_FFFFFF,t_70,g_se,x_16)

![在这里插入图片描述](https://img-blog.csdnimg.cn/ccbcff0bd76f41639887198bf064d81b.png?x-oss-process=image/watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBAQmlnIE9yYW5nZS4uLg==,size_20,color_FFFFFF,t_70,g_se,x_16)

             0sI无知


0sI无知

本文为转载文章,版权归原作者所有,不代表本站立场和观点。

很赞哦! () 有话说 ()