【问题标题】:WebRTC works locally, but not over Internet [duplicate]WebRTC 在本地工作,但不能通过 Internet [重复]
【发布时间】:2020-04-17 22:12:42
【问题描述】:

我正在尝试运行一个简单的概念验证 WebRTC 应用程序。我的代码可以在本地网络上运行,但不能在 Internet 上运行。

我相信我有一个错误outlined here,但我想不通。

server.js (expressjs)

require('dotenv').config();

const express = require('express');
const app = express();
const http = require('http').createServer(app);
const io = require('socket.io')(http);

app.use(express.static('public'));

io.on('connection', (socket) => {
    socket.on('join', () => socket.broadcast.emit('join', socket.id));
    socket.on('offer', (id, sdp) => socket.to(id).emit('offer', socket.id, sdp));
    socket.on('answer', (id, sdp) => socket.to(id).emit('answer', socket.id, sdp));
    socket.on('candidate', (id, candidate) => socket.to(id).emit('candidate', socket.id, candidate));
});

const port = process.env.PORT || 443;
http.listen(port, () => console.log("listening on :" + port));

client.js(使用 webpack 构建)

import io from 'socket.io-client';

console.log('getting video stream');
navigator.mediaDevices.getUserMedia({ video: true }).then(myStream => {
    const socket = io.connect();

    console.log('joining');
    socket.emit('join');

    let connections = {};

    socket.on('join', async peer_id => {
        const connection = newConnection(peer_id);

        console.log('creating offer');
        const sdp = await connection.createOffer();

        console.log('setting local desc');
        await connection.setLocalDescription(sdp);

        console.log('sending offer');
        socket.emit('offer', peer_id, connection.localDescription);
    });

    socket.on('offer', async (peer_id, remoteDescription) => {
        const connection = newConnection(peer_id);

        console.log('setting remote desc');
        await connection.setRemoteDescription(remoteDescription);

        console.log('creating answer');
        const sdp = await connection.createAnswer();

        console.log('setting local desc');
        await connection.setLocalDescription(sdp);

        console.log('sending answer');
        socket.emit('answer', peer_id, connection.localDescription);
    });

    socket.on('answer', (peer_id, remoteDescription) => {
        console.log('setting remote desc');
        connections[peer_id].setRemoteDescription(remoteDescription);
    });

    socket.on('candidate', (peer_id, candidate) => {
        console.log('adding candidate');
        connections[peer_id].addIceCandidate(candidate);
    });

    function newConnection(peer_id) {
        console.log('creating connection');
        const connection = new RTCPeerConnection(
            { iceServers: [{ urls: ['stun:stun.l.google.com:19302'] }] }
        );

        connections[peer_id] = connection;

        connection.onconnectionstatechange = () => console.log('connection state', connection.connectionState);

        console.log('searching for candidates');
        connection.onicecandidate = event => {
            if (event.candidate) {
                console.log('sending candidate');
                socket.emit('candidate', peer_id, event.candidate);
            } else {
                console.log('all candidates found');
            }
        };

        console.log('listening for tracks');
        connection.ontrack = event => {
            console.log('track received');
            const stream = new MediaStream();
            stream.addTrack(event.track);
            document.getElementById('video').srcObject = stream;
        };

        for (const track of myStream.getTracks()) {
            console.log('sending track');
            connection.addTrack(track);
        }

        return connection;
    }
});

来自本地网络对等方的日志(已连接)

第一个同伴

getting video stream
joining
creating connection
searching for candidates
listening for tracks
sending track
creating offer
setting local desc
sending offer
(2) sending candidate
setting remote desc
adding candidate
track received
connection state connecting
all candidates found
connection state connected

第二对

getting video stream
joining
creating connection
searching for candidates
listening for tracks
sending track
setting remote desc
track received
creating answer
setting local desc
sending answer
sending candidate
connection state connecting
all candidates found
connection state connected
(2) adding candidate

来自 Internet 上的同行的日志(失败)

第一个同伴

getting video stream
joining
creating connection
searching for candidates
listening for tracks
sending track
creating offer
setting local desc
sending offer
(3) sending candidate
all candidates found
setting remote desc
track received
connection state connecting
(5) adding candidate
connection state failed

第二对

getting video stream
joining
creating connection
searching for candidates
listening for tracks
sending track
setting remote desc
track received
creating answer
setting local desc
sending answer
(5) sending candidate
(3) adding candidate
connection state connecting
connection state failed
all candidates found

【问题讨论】:

    标签: webrtc


    【解决方案1】:

    除非您使用 TURN,否则 WebRTC 不会适用于所有连接配对。

    您会看到一些能够连接的同行,您可以在我的回答 here 中阅读所有重要的案例

    【讨论】:

    • 我不能让至少一种客户端组合进行连接吗?我已经尝试了我的家庭互联网、我的手机 5g 和 Verizon 热点的排列。
    • 我应该在 chrome://webrtc-internals/ 中寻找什么特别的东西吗?我在每个客户端上看到两个 udp 和一个 tcp (ipv4) 候选者。并且它们被适当地添加到它们的同龄人中。如果有什么方法可以让我看到这些候选人的状态?
    • 我继续尝试了一些 Twilio 转服务器,并且代码运行正常。所以,我想我可以放弃希望这里有一个错误。感谢您的帮助。
    • 乐于助人!很难追踪,因为它取决于每个连接(并且它们可能以不同的方式与每个连接进行交互)。如果您有两个使用同一个 ISP 的对等点,他们可能有不同的 NAT 类型等...github.com/enobufs/go-nats 是一个很酷的工具,可能会有所帮助!
    猜你喜欢
    • 2023-04-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-28
    • 1970-01-01
    • 1970-01-01
    • 2013-10-23
    • 1970-01-01
    相关资源
    最近更新 更多