我用数据通道编写了一个 webRTC 连接脚本。我只想为我的应用程序使用数据通道。当我一对一连接时,这工作正常。如果我使用多个连接,则不会创建数据通道。
例如:假设User A
,User B
并User 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));
}
通过以下方式向对等用户提供要约的步骤
用户
- 创建 RTC 对等连接对象
peerConnection
creating_data_channel()
通过调用函数创建数据通道create_offer_to_user()
通过调用函数创建报价
对等用户
- 收到 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
?请问有什么建议吗?