当两个对等点位于同一本地网络时,WebRTC 是否可以与对称 NAT 配合使用?

问题描述 投票:0回答:1

当对等方位于同一网络但位于具有对称 NAT 的路由器后面时,它们是否应该能够通过 WebRTC 进行连接?这样的话就不需要ICE服务器了,应该没有问题吧?

我有两个在同一台机器上的对等点尝试相互连接,但连接失败,但这是我第一次尝试使用 WebRTC 做某事,因此我的实现可能存在缺陷:P

在 Go 中提供 Peer:

package main

import (
    "fmt"
    "io"
    "net/http"
    "strconv"

    "github.com/pion/webrtc/v4"
)

func main() {
    answerC := HTTPSDPServer(8000) // feeds sdp into

    // Create a new RTCPeerConnection
    peerConnection, err := webrtc.NewPeerConnection(webrtc.Configuration{})
    if err != nil {
        panic(err)
    }
    defer func() {
        if cErr := peerConnection.Close(); cErr != nil {
            fmt.Printf("cannot close peerConnection: %v\n", cErr)
        }
    }()

    peerConnection.OnConnectionStateChange(func(s webrtc.PeerConnectionState) {
        fmt.Printf("Peer Connection State has changed: %s\n", s.String())
    })

    c, err := peerConnection.CreateDataChannel("channel", nil)
    if err != nil {
        panic(err)
    }

    c.OnOpen(func() {
        fmt.Println("Data Channel OPEN")
    })
    c.OnClose(func() {
        fmt.Println("Data Channel CLOSE")
    })

    offer, err := peerConnection.CreateOffer(nil)
    if err != nil {
        panic(err)
    }

    err = peerConnection.SetLocalDescription(offer)
    if err != nil {
        panic(err)
    }

    fmt.Println(strconv.Quote(offer.SDP)) // Copy this to frontend app

    answerStr := <-answerC
    answer := webrtc.SessionDescription{
        Type: webrtc.SDPTypeAnswer,
        SDP:  answerStr,
    }

    err = peerConnection.SetRemoteDescription(answer)
    if err != nil {
        panic(err)
    }

    select {}
}

func HTTPSDPServer(port int) chan string {
    sdpChan := make(chan string)
    http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
        body, _ := io.ReadAll(r.Body)
        fmt.Fprintf(w, "done")
        sdpChan <- string(body)
    })

    go func() {
        // nolint: gosec
        err := http.ListenAndServe(":"+strconv.Itoa(port), nil)
        if err != nil {
            panic(err)
        }
    }()

    return sdpChan
}

Vue 前端在启动时运行此脚本:

const remoteConnection = new RTCPeerConnection()

remoteConnection.onicecandidate = e => {
    console.log(" NEW ice candidnat!! on localconnection reprinting SDP ")
    console.log(JSON.stringify(remoteConnection.localDescription))
}


remoteConnection.ondatachannel = e => {
    const receiveChannel = e.channel;
    receiveChannel.onmessage = e => console.log("message: " + e.data)
    receiveChannel.onopen = e => console.log("Data Channel OPEN");
    receiveChannel.onclose = e => console.log("Data Channel CLOSED");
    remoteConnection.channel = receiveChannel;

}

var sdp = "PASTE OFFER HERE" // Paste SDP copied from the offering peer
var offer = { "type": "offer", "sdp": sdp }

remoteConnection.setRemoteDescription(offer).then(a => console.log("done"))

//create answer
await remoteConnection.createAnswer().then(a => remoteConnection.setLocalDescription(a)).then(a =>
    console.log(JSON.stringify(remoteConnection.localDescription)))

前端应用程序打印它的 sdp 后,它会在请求中发送到提供对等方的服务器以解除阻止并继续。没有错误,连接只是从“正在连接”变为“失败”。

webrtc backend communication p2p
1个回答
0
投票

事实证明我错误地处理了报价创建。 我创建了一个报价,将其设置为本地描述,然后直接使用它

    offer, err := peerConnection.CreateOffer(nil)
    if err != nil {
        panic(err)
    }

    err = peerConnection.SetLocalDescription(offer)
    if err != nil {
        panic(err)
    }

// then I referenced offer.SPD to get the SPD.

我需要做的是调用

webrtc.GatheringCompletePromise(peerConnection)
并等待它完成,然后使用
peerConnection.LocalDescription().SPD
而不是
offer.SPD

这是一个完整的例子

    offer, err := peerConnection.CreateOffer(nil)
    if err != nil {
        panic(err)
    }

    // Create channel that is blocked until ICE Gathering is complete
    gatherComplete := webrtc.GatheringCompletePromise(peerConnection)

    err = peerConnection.SetLocalDescription(offer)
    if err != nil {
        panic(err)
    }

    <-gatherComplete

// get SPD from peerConnection.LocalDescription().SPD
© www.soinside.com 2019 - 2024. All rights reserved.