RTCDataChannel 发送方法不发送数据
RTCDataChannel send method not sending data
我在使用 RTCDataChannel 时遇到了一个奇怪的问题。
我正在做一些关于 WebRTC 的研究,我已经开始使用 WebRTC audio/video 聊天了。现在我想使用 RTCDataChannel 添加文本聊天和文件共享。
我创建了这样的 RTCDataChannel:
var dataChannelOptions = {
reliable: true,
maxRetransmitTime: "2000"
};
dataChannel = yourConnection.createDataChannel("testDataChannel", dataChannelOptions);
dataChannel.onerror = function (error) {
console.log("dataChannel.OnError:", error);
};
dataChannel.onmessage = function (event) {
console.log("dataChannel.OnMessage:", event);
};
dataChannel.onopen = function (event) {
console.log("dataChannel.OnOpen", event);
dataChannel.send("Hello World!");
};
dataChannel.onclose = function (event) {
console.log("dataChannel.OnClose", event);
};
我在双方都收到的唯一信息是 dataChannel.onopen 第一行的日志。我没有收到来自 dataChannel.onmessage.
的日志
没有错误..
当我手动调用dataChannel.send时结果是一样的
测试于:
Google Chrome (50.0.2661.94)
火狐 (45.0.2)
有人可以帮忙吗?
这是人们常犯的错误,您在两个浏览器上都创建了数据通道,但都没有接受,您需要使用 RTCPeerConnection 的 ondatachannel
事件并设置监听器
我遇到了同样的问题。根据 RTCDataChannel 文档,您应该处理 Peer Connection 对象上的回调以接收数据通道上的数据。下面的代码可能会有帮助:
第 1 步:定义回调处理程序:
var handleDataChannelOpen = function (event) {
console.log("dataChannel.OnOpen", event);
dataChannel.send("Hello World!");
};
var handleDataChannelMessageReceived = function (event) {
console.log("dataChannel.OnMessage:", event);
};
var handleDataChannelError = function (error) {
console.log("dataChannel.OnError:", error);
};
var handleDataChannelClose = function (event) {
console.log("dataChannel.OnClose", event);
};
var handleChannelCallback = function (event) {
dataChannel = event.channel;
dataChannel.onopen = handleDataChannelOpen;
dataChannel.onmessage = handleDataChannelMessageReceived;
dataChannel.onerror = handleDataChannelError;
dataChannel.onclose = handleDataChannelClose;
};
第 2 步:创建 RTC 对等连接:
var pc = new RTCPeerConnection();
pc.ondatachannel = handleChannelCallback;
第 3 步:创建数据通道:
var dataChannel = pc.createDataChannel('dataChannelName', {});
dataChannel.onopen = handleDataChannelOpen;
dataChannel.onmessage = handleDataChannelMessageReceived;
dataChannel.onerror = handleDataChannelError;
dataChannel.onclose = handleDataChannelClose;
在您的代码中,您只需添加 ondatachannel 回调处理程序即可接收数据。
我认为最大的误解,至少对我来说,是每个客户端都需要保留对 两个 频道的引用(如果错误请纠正我,因为它不会感觉完全正确)。一个用于发送,一个用于接收。这基本上就是@Nikhil 的回答所显示的内容。他为处理程序创建命名函数,以便使用它们两次。
另请注意,您可以在 peerConnection 实例化后立即定义数据连接。我读过相互矛盾的说法,说你必须只从呼叫者那里做,或者只有在连接准备好之后。也许旧版本的 WebRTC 确实如此,但这适用于当前 chrome(截至 2017 年 10 月的任何版本)。
let pc = new RTCPeerConnection({"iceServers": [{"url": "stun:stun.l.google.com:19302"}]});
const handleDataChannelOpen = (event) =>{
console.log("dataChannel.OnOpen", event);
sendChannel.send("Hello World!");
};
const handleDataChannelMessageReceived = (event) =>{
console.log("dataChannel.OnMessage:", event);
};
const handleDataChannelError = (error) =>{
console.log("dataChannel.OnError:", error);
};
const handleDataChannelClose = (event) =>{
console.log("dataChannel.OnClose", event);
};
let sendChannel = pc.createDataChannel('text', {});
sendChannel.onopen = handleDataChannelOpen;
sendChannel.onmessage = handleDataChannelMessageReceived;
sendChannel.onerror = handleDataChannelError;
sendChannel.onclose = handleDataChannelClose;
pc.ondatachannel = (event) =>{
console.log("on data channel")
let receiveChannel = event.channel;
receiveChannel.onopen = handleDataChannelOpen;
receiveChannel.onmessage = handleDataChannelMessageReceived;
receiveChannel.onerror = handleDataChannelError;
receiveChannel.onclose = handleDataChannelClose;
let button = document.getElementById(this.id + "-submit");
button.onclick = () =>{
receiveChannel.send("hello from " + this.id)
};
};
//... do your connection with servers
这是有效的客户端代码,我在这里分享,可能对某人有所帮助。如果对您有帮助,请不胜感激:
var connection = new WebSocket('wss://127.0.0.1:3000');
var name = "";
var loginInput = document.querySelector('#loginInput');
var loginBtn = document.querySelector('#loginBtn');
var otherUsernameInput = document.querySelector('#otherUsernameInput');
var connectToOtherUsernameBtn = document.querySelector('#connectToOtherUsernameBtn');
var msgInput = document.querySelector('#msgInput');
var sendMsgBtn = document.querySelector('#sendMsgBtn');
var connectedUser, myConnection, dataChannel;
//when a user clicks the login button
loginBtn.addEventListener("click", function(event) {
name = loginInput.value;
if(name.length > 0) {
send({
type: "login",
name: name
});
}
});
//handle messages from the server
connection.onmessage = function (message) {
// if(message)
var data = JSON.parse(message.data);
console.log("Got message", data.type);
switch(data.type) {
case "login":
onLogin(data.success);
break;
case "offer":
onOffer(data.offer, data.name);
break;
case "answer":
onAnswer(data.answer);
break;
case "candidate":
onCandidate(data.candidate);
break;
default:
break;
}
};
//when a user logs in
function onLogin(success) {
if (success === false) {
alert("oops...try a different username");
} else {
//creating our RTCPeerConnection object
var configuration = {
"iceServers": [{ "url": "stun:stun.1.google.com:19302" }]
};
myConnection = new RTCPeerConnection(configuration);
console.log("RTCPeerConnection object was created");
console.log(myConnection);
//setup ice handling
//when the browser finds an ice candidate we send it to another peer
myConnection.onicecandidate = function (event) {
if (event.candidate) {
send({
type: "candidate",
candidate: event.candidate
});
}
};
myConnection.ondatachannel = function (event) {
var receiveChannel = event.channel;
receiveChannel.onmessage = function (event) {
console.log("ondatachannel message:", event.data);
};
};
openDataChannel();
console.log("DataChannel Opened..");
}
};
connection.onopen = function () {
console.log("Connected");
};
connection.onerror = function (err) {
console.log("Got error", err);
};
// Alias for sending messages in JSON format
function send(message) {
if (connectedUser) {
message.name = connectedUser;
}
connection.send(JSON.stringify(message));
};
//setup a peer connection with another user
connectToOtherUsernameBtn.addEventListener("click", function () {
var otherUsername = otherUsernameInput.value;
connectedUser = otherUsername;
if (otherUsername.length > 0) {
//make an offer
myConnection.createOffer(function (offer) {
console.log(offer);
send({
type: "offer",
offer: offer
});
myConnection.setLocalDescription(offer);
}, function (error) {
alert("An error has occurred.");
});
}
});
//when somebody wants to call us
function onOffer(offer, name) {
connectedUser = name;
myConnection.setRemoteDescription(new RTCSessionDescription(offer));
myConnection.createAnswer(function (answer) {
myConnection.setLocalDescription(answer);
send({
type: "answer",
answer: answer
});
}, function (error) {
alert("oops...error");
});
}
//when another user answers to our offer
function onAnswer(answer) {
myConnection.setRemoteDescription(new RTCSessionDescription(answer));
}
//when we got ice candidate from another user
function onCandidate(candidate) {
myConnection.addIceCandidate(new RTCIceCandidate(candidate));
}
//creating data channel
function openDataChannel() {
var dataChannelOptions = {
reliable:true
};
dataChannel = myConnection.createDataChannel("myDataChannel", dataChannelOptions);
dataChannel.onerror = function (error) {
console.log("Error:", error);
};
dataChannel.onmessage = function (event) {
console.log("Got message:", event.data);
};
}
//when a user clicks the send message button
sendMsgBtn.addEventListener("click", function (event) {
console.log("send message");
var val = msgInput.value;
dataChannel.send(val);
});
我在使用 RTCDataChannel 时遇到了一个奇怪的问题。
我正在做一些关于 WebRTC 的研究,我已经开始使用 WebRTC audio/video 聊天了。现在我想使用 RTCDataChannel 添加文本聊天和文件共享。
我创建了这样的 RTCDataChannel:
var dataChannelOptions = {
reliable: true,
maxRetransmitTime: "2000"
};
dataChannel = yourConnection.createDataChannel("testDataChannel", dataChannelOptions);
dataChannel.onerror = function (error) {
console.log("dataChannel.OnError:", error);
};
dataChannel.onmessage = function (event) {
console.log("dataChannel.OnMessage:", event);
};
dataChannel.onopen = function (event) {
console.log("dataChannel.OnOpen", event);
dataChannel.send("Hello World!");
};
dataChannel.onclose = function (event) {
console.log("dataChannel.OnClose", event);
};
我在双方都收到的唯一信息是 dataChannel.onopen 第一行的日志。我没有收到来自 dataChannel.onmessage.
的日志没有错误..
当我手动调用dataChannel.send时结果是一样的
测试于:
Google Chrome (50.0.2661.94)
火狐 (45.0.2)
有人可以帮忙吗?
这是人们常犯的错误,您在两个浏览器上都创建了数据通道,但都没有接受,您需要使用 RTCPeerConnection 的 ondatachannel
事件并设置监听器
我遇到了同样的问题。根据 RTCDataChannel 文档,您应该处理 Peer Connection 对象上的回调以接收数据通道上的数据。下面的代码可能会有帮助:
第 1 步:定义回调处理程序:
var handleDataChannelOpen = function (event) {
console.log("dataChannel.OnOpen", event);
dataChannel.send("Hello World!");
};
var handleDataChannelMessageReceived = function (event) {
console.log("dataChannel.OnMessage:", event);
};
var handleDataChannelError = function (error) {
console.log("dataChannel.OnError:", error);
};
var handleDataChannelClose = function (event) {
console.log("dataChannel.OnClose", event);
};
var handleChannelCallback = function (event) {
dataChannel = event.channel;
dataChannel.onopen = handleDataChannelOpen;
dataChannel.onmessage = handleDataChannelMessageReceived;
dataChannel.onerror = handleDataChannelError;
dataChannel.onclose = handleDataChannelClose;
};
第 2 步:创建 RTC 对等连接:
var pc = new RTCPeerConnection();
pc.ondatachannel = handleChannelCallback;
第 3 步:创建数据通道:
var dataChannel = pc.createDataChannel('dataChannelName', {});
dataChannel.onopen = handleDataChannelOpen;
dataChannel.onmessage = handleDataChannelMessageReceived;
dataChannel.onerror = handleDataChannelError;
dataChannel.onclose = handleDataChannelClose;
在您的代码中,您只需添加 ondatachannel 回调处理程序即可接收数据。
我认为最大的误解,至少对我来说,是每个客户端都需要保留对 两个 频道的引用(如果错误请纠正我,因为它不会感觉完全正确)。一个用于发送,一个用于接收。这基本上就是@Nikhil 的回答所显示的内容。他为处理程序创建命名函数,以便使用它们两次。
另请注意,您可以在 peerConnection 实例化后立即定义数据连接。我读过相互矛盾的说法,说你必须只从呼叫者那里做,或者只有在连接准备好之后。也许旧版本的 WebRTC 确实如此,但这适用于当前 chrome(截至 2017 年 10 月的任何版本)。
let pc = new RTCPeerConnection({"iceServers": [{"url": "stun:stun.l.google.com:19302"}]});
const handleDataChannelOpen = (event) =>{
console.log("dataChannel.OnOpen", event);
sendChannel.send("Hello World!");
};
const handleDataChannelMessageReceived = (event) =>{
console.log("dataChannel.OnMessage:", event);
};
const handleDataChannelError = (error) =>{
console.log("dataChannel.OnError:", error);
};
const handleDataChannelClose = (event) =>{
console.log("dataChannel.OnClose", event);
};
let sendChannel = pc.createDataChannel('text', {});
sendChannel.onopen = handleDataChannelOpen;
sendChannel.onmessage = handleDataChannelMessageReceived;
sendChannel.onerror = handleDataChannelError;
sendChannel.onclose = handleDataChannelClose;
pc.ondatachannel = (event) =>{
console.log("on data channel")
let receiveChannel = event.channel;
receiveChannel.onopen = handleDataChannelOpen;
receiveChannel.onmessage = handleDataChannelMessageReceived;
receiveChannel.onerror = handleDataChannelError;
receiveChannel.onclose = handleDataChannelClose;
let button = document.getElementById(this.id + "-submit");
button.onclick = () =>{
receiveChannel.send("hello from " + this.id)
};
};
//... do your connection with servers
这是有效的客户端代码,我在这里分享,可能对某人有所帮助。如果对您有帮助,请不胜感激:
var connection = new WebSocket('wss://127.0.0.1:3000');
var name = "";
var loginInput = document.querySelector('#loginInput');
var loginBtn = document.querySelector('#loginBtn');
var otherUsernameInput = document.querySelector('#otherUsernameInput');
var connectToOtherUsernameBtn = document.querySelector('#connectToOtherUsernameBtn');
var msgInput = document.querySelector('#msgInput');
var sendMsgBtn = document.querySelector('#sendMsgBtn');
var connectedUser, myConnection, dataChannel;
//when a user clicks the login button
loginBtn.addEventListener("click", function(event) {
name = loginInput.value;
if(name.length > 0) {
send({
type: "login",
name: name
});
}
});
//handle messages from the server
connection.onmessage = function (message) {
// if(message)
var data = JSON.parse(message.data);
console.log("Got message", data.type);
switch(data.type) {
case "login":
onLogin(data.success);
break;
case "offer":
onOffer(data.offer, data.name);
break;
case "answer":
onAnswer(data.answer);
break;
case "candidate":
onCandidate(data.candidate);
break;
default:
break;
}
};
//when a user logs in
function onLogin(success) {
if (success === false) {
alert("oops...try a different username");
} else {
//creating our RTCPeerConnection object
var configuration = {
"iceServers": [{ "url": "stun:stun.1.google.com:19302" }]
};
myConnection = new RTCPeerConnection(configuration);
console.log("RTCPeerConnection object was created");
console.log(myConnection);
//setup ice handling
//when the browser finds an ice candidate we send it to another peer
myConnection.onicecandidate = function (event) {
if (event.candidate) {
send({
type: "candidate",
candidate: event.candidate
});
}
};
myConnection.ondatachannel = function (event) {
var receiveChannel = event.channel;
receiveChannel.onmessage = function (event) {
console.log("ondatachannel message:", event.data);
};
};
openDataChannel();
console.log("DataChannel Opened..");
}
};
connection.onopen = function () {
console.log("Connected");
};
connection.onerror = function (err) {
console.log("Got error", err);
};
// Alias for sending messages in JSON format
function send(message) {
if (connectedUser) {
message.name = connectedUser;
}
connection.send(JSON.stringify(message));
};
//setup a peer connection with another user
connectToOtherUsernameBtn.addEventListener("click", function () {
var otherUsername = otherUsernameInput.value;
connectedUser = otherUsername;
if (otherUsername.length > 0) {
//make an offer
myConnection.createOffer(function (offer) {
console.log(offer);
send({
type: "offer",
offer: offer
});
myConnection.setLocalDescription(offer);
}, function (error) {
alert("An error has occurred.");
});
}
});
//when somebody wants to call us
function onOffer(offer, name) {
connectedUser = name;
myConnection.setRemoteDescription(new RTCSessionDescription(offer));
myConnection.createAnswer(function (answer) {
myConnection.setLocalDescription(answer);
send({
type: "answer",
answer: answer
});
}, function (error) {
alert("oops...error");
});
}
//when another user answers to our offer
function onAnswer(answer) {
myConnection.setRemoteDescription(new RTCSessionDescription(answer));
}
//when we got ice candidate from another user
function onCandidate(candidate) {
myConnection.addIceCandidate(new RTCIceCandidate(candidate));
}
//creating data channel
function openDataChannel() {
var dataChannelOptions = {
reliable:true
};
dataChannel = myConnection.createDataChannel("myDataChannel", dataChannelOptions);
dataChannel.onerror = function (error) {
console.log("Error:", error);
};
dataChannel.onmessage = function (event) {
console.log("Got message:", event.data);
};
}
//when a user clicks the send message button
sendMsgBtn.addEventListener("click", function (event) {
console.log("send message");
var val = msgInput.value;
dataChannel.send(val);
});