首页 > 解决方案 > WebRTC (simple-peer) + STUN 没有额外的信号?

问题描述

我正在尝试使用 simple-peer 库来建立浏览器到浏览器的 WebRTC 连接(数据通道)。我的理解(也许我有一些误解)为了让两个浏览器通过 WebRTC 连接,它们必须交换 SDP 数据并执行 NAT 遍历。为了做到这一点,可以实现一个 STUN 服务器。

在 simple-peer 库中,他们声明 simple-peer 没有实现信令协议,但它确实提供了一种提供 STUN/ICE 服务器的方法。从他们的网格示例中考虑以下三个 HTML 文件:

peer1.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Peer1</title>
</head>
<body>
<script src="../../js/simplepeer.min.js"></script>
<script>
    // These are peer1's connections to peer2 and peer3
    var peer2 = new SimplePeer({ initiator: true, config: {
            iceServers: [
                {urls: 'stun:stun.a-mm.tv:3478'}
            ]
        } })
    var peer3 = new SimplePeer({ initiator: true, config: {
            iceServers: [
                {urls: 'stun:stun.a-mm.tv:3478'}
            ]
        } })

    peer2.on('signal', data => {
        console.log(data)
    })

    peer2.on('connect', () => {
        peer2.send('hi peer2, this is peer1')
    })

    peer2.on('data', data => {
        console.log('got a message from peer2: ' + data)
    })

    peer3.on('signal', data => {
        console.log(data)
    })

    peer3.on('connect', () => {
        peer3.send('hi peer3, this is peer1')
    })

    peer3.on('data', data => {
        console.log('got a message from peer3: ' + data)
    })
</script>
</body>
</html>```

peer2.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Peer2</title>
</head>
<body>
<script src="../../js/simplepeer.min.js"></script>
<script>
    // These are peer2's connections to peer1 and peer3
    var peer1 = new SimplePeer({
        config: {
            iceServers: [
                {urls: 'stun:stun.a-mm.tv:3478'}
            ]
        }
    })
    var peer3 = new SimplePeer({ initiator: true, config: {
            iceServers: [
                {urls: 'stun:stun.a-mm.tv:3478'}
            ]
        } })

    peer1.on('signal', data => {
        console.log(data)
    })

    peer1.on('connect', () => {
        peer1.send('hi peer1, this is peer2')
    })

    peer1.on('data', data => {
        console.log('got a message from peer1: ' + data)
    })

    peer3.on('signal', data => {
        console.log(data)
    })

    peer3.on('connect', () => {
        peer3.send('hi peer3, this is peer2')
    })

    peer3.on('data', data => {
        console.log('got a message from peer3: ' + data)
    })
</script>
</body>
</html>

peer3.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Peer3</title>
</head>
<body>
<script src="../../js/simplepeer.min.js"></script>
<script>
    // These are peer3's connections to peer1 and peer2
    var peer1 = new SimplePeer({
            config: {
                iceServers: [
                    {urls: 'stun:stun.a-mm.tv:3478'}
                ]
            }
        }
    )
    var peer2 = new SimplePeer({
        config: {
            iceServers: [
                {urls: 'stun:stun.a-mm.tv:3478'}
            ]
        }
    })

    peer1.on('signal', data => {
        console.log(data)
    })

    peer1.on('connect', () => {
        peer1.send('hi peer1, this is peer3')
    })

    peer1.on('data', data => {
        console.log('got a message from peer1: ' + data)
    })

    peer2.on('signal', data => {
        console.log(data)
    })

    peer2.on('connect', () => {
        peer2.send('hi peer2, this is peer3')
    })

    peer2.on('data', data => {
        console.log('got a message from peer2: ' + data)
    })
</script>
</body>
</html>

你可以看到我在那里添加了两个 STUN 服务器。STUN 不交换必要的信令数据吗?但是,在查看他们的问题时,他们建议使用 websockets 来交换此类数据。那么我是否假设 STUN 只是为了让每个对等方都可以首先收集 SDP 信息,然后必须使用 websockets 来交换它?那么,在那之后,浏览器可以相互建立数据通道吗?

为什么我认为 STUN 会处理这个?当 STUN 已经能够向客户端提供数据时,引入 websocket 似乎有点多余。目标当然是尽快放弃所有中央服务器通信,转而支持浏览器到浏览器的数据通道。

一个好的答案可能会回答这些问题并修改示例。

标签: javascriptwebsocketwebrtcsimple-peer

解决方案


我的理解(也许我有一些误解)为了让两个浏览器通过 WebRTC 连接,它们必须交换 SDP 数据......

是的,这是正确的。

...并执行 NAT 遍历。

他们必须通过 ICE 建立连接,这可能涉及 NAT 穿越,是的。

为了做到这一点,可以实现一个 STUN 服务器。

STUN 服务器唯一要做的就是尝试找出可公开访问的 IP 地址是什么。NAT 后面的客户端知道它自己的本地地址,但可能不知道它的公共 IP 地址,因为它位于执行 NAT 的路由器的另一端。因此,一些外部服务器可以回复并告诉它客户端连接的 IP 地址。

STUN 不交换必要的信令数据吗?

STUN 服务器根本不发出任何信号。没有任何。信号由您决定,可以通过您选择的任何方法来实现。

那么我是否假设 STUN 只是为了让每个对等方都可以首先收集 SDP 信息......

主要是针对 ICE 候选人(主要是 IP 地址和其他一些信息)。SDP信息主要由客户端的能力组成。(支持哪些编解码器以及以什么速率等)

...然后必须使用 websockets 来交换它?

它不必是网络套接字。可以使用任何双向通信方法,但通常使用 Web 套接字。

目标当然是尽快放弃所有中央服务器通信,转而支持浏览器到浏览器的数据通道。

是的,不幸的是,WebRTC 的当前状态下降了,远未达到这一点。如果网络上的客户可以互相交谈,那就太棒了……沟通的基础。可悲的是,事实并非如此。仍然需要集中式服务器来协调一切。对等连接仅在其他地方发生连接设置后进行。


推荐阅读