首页 > 解决方案 > WebRTC 数据通道不适用于多连接

问题描述

我用数据通道编写了一个 webRTC 连接脚本。我只想为我的应用程序使用数据通道。当我一对一连接时,这工作正常。如果我使用多个连接,则不会创建数据通道。

例如:假设User AUser BUser C已连接到应用程序。连接时数据通道工作正常User A -> User B。在此连接之后,如果我尝试过,User A -> User C则数据通道不会在User C侧面打开。这是我目前面临的问题。

这是用于 webRTC 连接和数据通道创建的代码。

var dataChannel, peerConnection;

var configuration = {
    "iceServers": [
        {
            "urls": "stun:stun.1.google.com:19302"
        }
    ]
};


peerConnection = new RTCPeerConnection(configuration);
peerConnection.onicecandidate = icecandidateAdded;
peerConnection.ondatachannel = handleChannelCallback;


function icecandidateAdded(ev) {
    
    if (ev.candidate) {
        sendToServer(ev.candidate) ; //send  ICE to signaling server
    }
};

var handleChannelCallback = function (event) {
dataChannel = event.channel;
dataChannel.onopen = handleDataChannelOpen;
dataChannel.onmessage = handleDataChannelMessageReceived;
dataChannel.onerror = handleDataChannelError;
dataChannel.onclose = handleDataChannelClose;

};

数据通道回调是

var handleDataChannelOpen = function (event) {
    console.log("dataChannel.OnOpen", event);
};
var handleDataChannelError = function (error) {
    console.log("dataChannel.OnError:", error);
};
var handleDataChannelClose = function (event) {
    console.log("dataChannel.OnClose", event);
};
var handleDataChannelMessageReceived = function (event) {
    console.log("dataChannel.OnMessage:", event);
};

创建数据通道的函数

function creating_data_channel()
{
    const dataChannelOptions = {
        ordered: false, // do not guarantee order
        maxPacketLifeTime: 3000, // in milliseconds
    };

    dataChannel = peerConnection.createDataChannel("mychannel", dataChannelOptions);
    dataChannel.onopen = handleDataChannelOpen;
    dataChannel.onmessage = handleDataChannelMessageReceived;
    dataChannel.onerror = handleDataChannelError;
    dataChannel.onclose = handleDataChannelClose;
}

创建报价

function create_offer_to_user()
{
    try {
        const offer = await peerConnection.createOffer({ iceRestart: true });
        await peerConnection.setLocalDescription(offer);

        sendToServer(offer) ; // send offer to signaling server

    } catch (e) {
        console.log("Failed to create offer:" + e);
    }
}

为报价创建答案

function create_answer_for_user(offer) {

    peerConnection.setRemoteDescription(new RTCSessionDescription(offer));
    peerConnection.createAnswer()
    .then(function(answer) {
        
        peerConnection.setLocalDescription(answer);
        sendToServer(answer) ; // send anser to signaling server
    })
    .catch(function(err) {
        console.log(err.name + ': ' + err.message);
  });
    
}

设置 ICE 候选和答案

function update_ice_candidate(candidate) {
    peerConnection.addIceCandidate(new RTCIceCandidate(candidate));
}

function received_answer_from_user(answer) {
    peerConnection.setRemoteDescription(new RTCSessionDescription(answer));
}

通过以下方式向对等用户提供要约的步骤

用户

  1. 创建 RTC 对等连接对象peerConnection
  2. creating_data_channel()通过调用函数创建数据通道
  3. create_offer_to_user()通过调用函数创建报价

对等用户

  1. 收到 offer 请求后,peer 将通过create_answer_for_user()函数创建答案。

每次与对等方连接后,我都会按dataChannel.close()方法关闭数据通道。

在双方 ICE 和 Answer 将通过update_ice_candidate()received_answer_from_user()功能完成

这可以按预期进行User A -> User B连接。我可以在用户 A 和用户 B 中看到浏览器控制台日志消息dataChannel.OnOpen(我对用户和对等方都使用 Firefox。)但是当我连接时,我只能在用户 AUser A -> User C中看到控制台日志消息。不在用户 C 中。dataChannel.OnOpen

最初我收到了一些与 ICE 相关的其他错误。那是

Uncaught (in promise) DOMException: Remote description indicates ICE restart but offer did not request ICE restart (new remote description changes either the ice-ufrag or ice-pwd)

Uncaught (in promise) DOMException: Unknown ufrag (6d054db2)

我已经iceRestart在报价中修复了这些错误。

const offer = await peerConnection.createOffer({ iceRestart: true });

在此修复后,我看不到该错误,但现在数据通道未在另一侧打开。

现在我怀疑 ICE 候选人流程。代码有问题吗?为什么这适用于user A->B而不适用于user A->C?请问有什么建议吗?

标签: javascriptwebrtcsdprtcdatachannel

解决方案


推荐阅读