Skip to content

Instantly share code, notes, and snippets.

@alexzhang1030
Last active June 13, 2024 03:21
Show Gist options
  • Save alexzhang1030/5ce0804843cf464a536cb14ee4db567d to your computer and use it in GitHub Desktop.
Save alexzhang1030/5ce0804843cf464a536cb14ee4db567d to your computer and use it in GitHub Desktop.
WebRTC Note Draft

WebRTC

目前仅存储有关 DataChannel 的信息

通信模型

在进行 WebRTC 通信时,节点间会按照如下顺序获取对方的地址:

  • 如果双端在同一个内网,直接用内网IP通信;
  • 通过 STUN 服务器,为双端构造可以直接访问的地址,打造一条可以穿透 NAT 的通路,俗称“打洞”;
  • 双端通过 TURN 服务器(中继服务器)进行通信。此时,通信网络的拓扑结构不再是 P2P ,因为数据其实是经过 TURN 服务器转发给双端的。

Signalling 信令服务

理想情况下,连接双方都是公网 IP,可以直接进行点对点连接。但是大部分情况下都不是这样的,需要一个信令服务来交换双方的网络信息,并通过 ICE 服务(STUN 协议)来打洞实现点对点链接。

连接

大概的流程是

// 1. 创建一个 PeerConnection
const peerConnection = new RTCPeerConnection({
  // stun/turn 服务,用于打洞
  iceServers: [
    {
      urls: "stun:stun3.l.google.com:19302",
    },
  ],
});

// 设置 icecandidate (这一步是交换网络信息)
senderPeerConnection.onicecandidate = (e) =>
    !e.candidate ||
    receiverPeerConnection
      .addIceCandidate(e.candidate)
      .catch(handleAddCandidateError);

receiverPeerConnection.onicecandidate = (e) =>
	!e.candidate ||
	senderPeerConnection
	  .addIceCandidate(e.candidate)
	  .catch(handleAddCandidateError);

// 2. 如果需要点对点连接,双方需要发起申请并应答
const offer = await senderPeerConnection.createOffer();
// 创建完 offer 应立刻设置,offer 需要通过信令服务传输
senderPeerConnection.setLocalDescription(offer);

// 接收方拿到 offer 设置 remoteDescription
// 并创建 answer 给 sender
receiverPeerConnection.setRemoteDescription(offer);
const answer = await receiverPeerConnection.createAnswer();
receiverPeerConnection.setLocalDescription(answer);

// sender 拿到 answer 并设置
senderPeerConnection.setRemoteDescription(data);

由此双方可建立联系

DataChannel

// sender
const senderChannel = senderPeerConnection.createDataChannel("desc"));

// receiver
receiverPeerConnection.ondatachannel = (data) => {
  const receiverChannel = data.channel
}

事件

channel.onopen = () => {  }
channel.onmessage = () => {  }

自建 stun 服务

coturn

用 Docker

docker run -d -p 3478:3478 -p 3478:3478/udp -p 5349:5349 -p 5349:5349/udp -p 49152-65535:49152-65535/udp coturn/coturn

注意: port range 越大启动的速度越慢,可以稍微减少一些

Or just use the host network directly (recommended, as Docker performs badly with large port ranges):

docker run -d --network=host coturn/coturn

docker-compose.yaml

version: '3'

services:
  coturn:
    image: coturn/coturn
    container_name: coturn_server
    network_mode: host
    restart: unless-stopped
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment