RTCDataChannel发送方法未发送数据
RTCDataChannel send method not sending data
我的RTCDataChannel出现了一个奇怪的问题。
我正在做一些关于WebRTC的研究,我已经在做WebRTC音频/视频聊天了。现在我想使用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.onpen第一行的日志。我没有从dataChannel.onmessage收到日志。
没有错误。。
当我手动调用dataChannel.send时,结果是相同的。
测试日期:
谷歌浏览器(50.0.2661.94)
Firefox(45.0.2)
有人能帮忙吗?
这是人们常犯的错误,您在两个浏览器上都创建了数据通道,但在任何一个浏览器上均不接受,您需要使用RTCPeerConnection的ondatachannel
事件并将侦听器设置为
我也面临同样的问题。根据RTCDataChannel文档,您应该处理对等连接对象上的回调,以接收数据通道上的数据。以下代码可能会有所帮助:
步骤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 "answerswer":
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: "answerswer",
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);
});
- 序列化数据属性中对象的最可靠方法
- 有没有一种方法可以仅使用HTML/CSS来隐藏基于特定值的数据单元格
- 如何在从客户端接收数据时从本机方法触发javascript函数?
- 我们可以用参数对象集合而不是原始数据来调用JavaScript collection.reduce()方法吗
- 在put方法之前从作用域获取数据
- 使用ReactJS和Flux架构从服务器获取数据的正确方法是什么
- 有没有一种方法可以使用Javascript检索谷歌表单ITSELF(而不是电子表格)的数据
- 有没有一种简单的方法可以用Lodash映射嵌套数据
- 数据属性有没有更干净的方法
- 将数据从promise then方法传递到对象方法
- 有没有更好的方法可以测量从Ajax调用返回数据所需的总时间
- ExtJS :: 存储加载数据方法优化
- 如何通过javascript触发rail的数据方法=“删除”
- 使用 jquery ajax 上传文件的数据方法设置
- 使用 d3 js 库的数据方法将事件绑定到动态生成的内容
- 插件内部jquery数据方法的奇怪行为
- 访问自定义组件数据/方法
- 为什么数据方法在获取ID时不能正常工作
- 为什么jQuery'数据方法的行为是这样的?(可能是错误?)
- jQuery数据方法返回整数而不是字符串