如何连接超过 2 个对等点?

Posted

技术标签:

【中文标题】如何连接超过 2 个对等点?【英文标题】:How can I connect more than 2 peers? 【发布时间】:2020-02-04 09:45:33 【问题描述】:

我希望能够使用 WebRTC 连接任意数量的对等点,并允许它们使用数据通道相互通信。 到目前为止,2 个选项卡中的 2 个本地对等点已经可以成功连接并发送“Hello!”彼此:

<meta charset="utf-8">
<script>
const server = new WebSocket('ws://localhost:1234');

let peer;
let send_channel;

server.onmessage = function(event) 
  const data = JSON.parse(event.data);
  if(data.type == 'offer') 
    peer.setRemoteDescription(new RTCSessionDescription(data));
    peer.createAnswer()
      .then(answer => peer.setLocalDescription(answer))
      .then(() => server.send(JSON.stringify(peer.localDescription)));
   else if(data.type == 'answer') 
    peer.setRemoteDescription(new RTCSessionDescription(data));
   else if(data.type == 'candidate') 
    peer.addIceCandidate(new RTCIceCandidate(
      candidate: data.candidate,
      sdpMid: data.sdpMid
    ));
  


server.onopen = function(event) 
  peer = new RTCPeerConnection();
  send_channel = peer.createDataChannel('channel');

  send_channel.onopen = function(event) 
    console.log('Send channel opened:', event);
  
  send_channel.onclose = function(event) 
    console.log('Send channel closed:', event);
  

  peer.ondatachannel = function(event) 
    event.channel.onopen = function(event) 
      console.log('Receive channel opened:', event);
      send_channel.send('Hello!');
    
    event.channel.onclose = function(event) 
      console.log('Receive channel closed:', event);
    
    event.channel.onmessage = function(event) 
      console.log('Message received:', event);
    
  

  peer.onicecandidate = function(event) 
    if (event.candidate) 
      server.send(JSON.stringify(
        
          type: 'candidate',
          candidate: event.candidate.candidate,
          sdpMid: event.candidate.sdpMid
        
      ));
    
  ;

  const offer = peer.createOffer()
    .then(offer => peer.setLocalDescription(offer))
    .then(() => server.send(JSON.stringify(peer.localDescription)));

</script>

两个选项卡中的控制台输出都是这样的:

Send channel opened: 
open  target: RTCDataChannel, … 
Receive channel opened: 
open  target: RTCDataChannel, … 
Message received: 
message  data: "Hello!", … 

localhost:1234 我有一个正在运行的信号服务器,它允许 WebSocket 连接并升级连接,每当一条消息发送到 WebSocket 时,服务器只会将该消息发送到所有其他连接的 WebSocket,除了发送的 WebSocket消息。

但现在我不确定如何连接超过 2 个对等点。 如果我打开第三个选项卡并尝试连接,我会在所有选项卡的控制台中收到此错误消息:InvalidStateError: Cannot set remote answer in state stable 并且连接中断。

【问题讨论】:

【参考方案1】:

WebRTC 仅支持 1:1 连接。对于每个想要加入您的网格的新对等点,您将需要创建另一个 PeerConnection。您尝试实现的通常称为 Mesh Topology 我也会研究 SFU,因为您的扩展可能会达到带宽/CPU 限制。

在您的信令代码中,您可能需要具有某种唯一 ID,然后将消息发送到不同的 PeerConnections。拓扑将如下所示。

【讨论】:

你认为我应该使用服务器而不是点对点吗?多个对等点似乎很复杂。 两者各有利弊!以下是我能想到的——Pro P2P(E2E 安全,无需付费/管理媒体服务器)——Pro Server(用户只需上传一次,更易于调试)

以上是关于如何连接超过 2 个对等点?的主要内容,如果未能解决你的问题,请参考以下文章

如何在对等js中建立对等点之间的连接

检测 WebRTC 连接中的离线对等点

多点连接手动管理对等点

芹菜错误“对等方重置连接”

Multipeer Connectivity - 检查所有附近的对等点是不是已连接并尝试重新连接它们

在 MCSession 中设置最大对等点