javascript-Firefox启动连接时,无法在Chrome中使用WebRTC数据通道
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了javascript-Firefox启动连接时,无法在Chrome中使用WebRTC数据通道,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含10002字,纯文字阅读大概需要15分钟。
内容图文
![javascript-Firefox启动连接时,无法在Chrome中使用WebRTC数据通道](/upload/InfoBanner/zyjiaocheng/659/2224089526c347c180e70334dcbbaf77.jpg)
我正在尝试使用WebRTC DataChannel创建一个简单的网页,以在浏览器之间发送ping / pong.
Chrome启动连接后,Chrome便开始工作.
当Firefox启动连接,然后Firefox连接时,它可以工作.
当Chrome启动连接,然后Firefox连接时,它开始工作.
但是,当Firefox启动连接,然后Chrome连接时,它不起作用. Chrome永远不会接收Firefox发送的数据.
我在Archlinux上使用Firefox 26和Chromium 32.
这是我的JavaScript代码:
<!DOCTYPE html>
<html>
<head>
<title>WebRTC test</title>
<meta charset="utf-8">
</head>
<body>
<button id="create" disabled>Create data channel</button>
<script type="text/javascript">
// DOM
var create = document.getElementById('create');
// Compatibility
window.RTCPeerConnection = window.RTCPeerConnection || window.mozRTCPeerConnection || window.webkitRTCPeerConnection;
window.RTCSessionDescription = window.RTCSessionDescription || window.mozRTCSessionDescription || window.webkitRTCSessionDescription;
window.RTCIceCandidate = window.RTCIceCandidate || window.mozRTCIceCandidate || window.webkitRTCIceCandidate;
// Create a WebRTC object
var rtc = new RTCPeerConnection(null);
// Create a data channel
var sendChannel = rtc.createDataChannel('pingtest', {reliable: false});
var myMsg = 'ping';
function setRecvChannel(recvChannel) {
recvChannel.onmessage = function(event) {
if(event.data.indexOf('\x03\x00\x00\x00\x00\x00\x00\x00\x00') === 0) {
console.log('-> ' + window.btoa(event.data));
return; // Received channel's name, ignore
}
console.log('-> ' + event.data);
window.setTimeout(function() {
console.log('<- ' + myMsg);
sendChannel.send(myMsg);
}, 500);
};
}
// Chrome and Firefox
sendChannel.onopen = function(event) {
setRecvChannel(sendChannel);
if(myMsg === 'ping') {
console.log('<- ' + myMsg);
sendChannel.send(myMsg);
}
};
// Firefox
rtc.ondatachannel = function(event) {
setRecvChannel(event.channel);
};
// ICE
rtc.onicecandidate = function(event) {
if(event.candidate) {
console.log('<- ' + JSON.stringify(event.candidate));
ws.send(JSON.stringify(event.candidate));
}
};
// Signaling channel
var ws = new WebSocket('ws://127.0.0.1:49300/');
ws.onopen = function() {
create.disabled = false;
};
ws.onmessage = function(event) {
console.log('-> ' + event.data);
var data = JSON.parse(event.data);
if(data.sdp) {
rtc.setRemoteDescription(new RTCSessionDescription(data));
if(data.type === 'offer') {
myMsg = 'pong';
rtc.createAnswer(function(anwser) {
rtc.setLocalDescription(anwser, function () {
console.log('<- ' + JSON.stringify(anwser));
ws.send(JSON.stringify(anwser));
});
}, console.error);
}
}
else {
rtc.addIceCandidate(new RTCIceCandidate(data));
}
};
ws.onclose = function() {
create.disabled = true;
};
// Create an offer
create.onclick = function() {
rtc.createOffer(function(offer) {
rtc.setLocalDescription(offer, function () {
offer.sdp = offer.sdp;
console.log(offer.sdp);
console.log('<- ' + JSON.stringify(offer));
ws.send(JSON.stringify(offer));
});
}, console.error);
};
</script>
</body>
</html>
这是我仅出于测试目的而创建的基于WebSocket的信令服务器,它仅侦听端口49300并将从客户端接收的数据广播到其他客户端:
#!/usr/bin/python
#-*- encoding: Utf-8 -*-
from socket import socket, AF_INET, SOCK_STREAM, SOL_SOCKET, SO_REUSEADDR
from string import printable
from threading import Thread
from base64 import b64encode
from struct import unpack
from hashlib import sha1
PORT = 49300
activeSocks = []
def SignalingChannel(ip, port, sock):
print 'Connection from %s:%s' % (ip, port)
# Handling the HTTP request
try:
headers = sock.recv(8184)
assert headers.upper().startswith('GET')
assert headers.endswith('\r\n\r\n')
data = headers.strip().replace('\r', '').split('\n')[1:]
headers = {}
for header in data:
name, value = header.split(':', 1)
headers[name.strip().lower()] = value.strip()
assert headers['host']
assert 'upgrade' in headers['connection'].lower()
assert 'websocket' in headers['upgrade'].lower()
assert headers['sec-websocket-version'] == '13'
assert len(headers['sec-websocket-key']) == 24
guid = '258EAFA5-E914-47DA-95CA-C5AB0DC85B11'
accept = b64encode(sha1(headers['sec-websocket-key'] + guid).digest())
sock.send('HTTP/1.1 101 Switching Protocols\r\n' +
'Connection: Upgrade\r\n' +
'Upgrade: websocket\r\n' +
'Sec-WebSocket-Accept: %s\r\n' % accept +
'\r\n')
except:
try:
msg = 'This is a RFC 6455 WebSocket server.\n'
sock.send('HTTP/1.1 400 Bad Request\r\n' +
'Connection: Close\r\n' +
'Content-Length: %d\r\n' % len(msg) +
'Content-Type: text/plain; charset=us-ascii\r\n' +
'Sec-WebSocket-Version: 13\r\n' +
'\r\n' +
msg)
except:
pass
sock.close()
print 'Disconnection from %s:%s' % (ip, port)
return
activeSocks.append(sock)
try:
data = sock.recv(2)
while len(data) == 2:
frame = data[0] + chr(ord(data[1]) & 0b01111111)
opcode = ord(data[0]) & 0b00001111
mask = ord(data[1]) & 0b10000000
paylen = ord(data[1]) & 0b01111111
if paylen == 126:
data = sock.recv(2)
frame += data
paylen = unpack('>H', data)[0]
elif paylen == 127:
data = sock.recv(8)
frame += data
paylen = unpack('>Q', data)[0]
if mask:
mask = sock.recv(4)
data = ''
received = True
while received and len(data) < paylen:
received = sock.recv(paylen - len(data))
data += received
if mask:
unmasked = ''
for i in xrange(len(data)):
unmasked += chr(ord(data[i]) ^ ord(mask[i % 4]))
else:
unmasked = data
frame += unmasked
if opcode != 8:
print '-- From port %d --' % port
if all(ord(c) < 127 and c in printable for c in unmasked):
print unmasked
else:
print repr(unmasked)
for destSock in activeSocks:
if destSock != sock:
destSock.send(frame)
else:
break
data = sock.recv(2)
except:
pass
activeSocks.remove(sock)
sock.close()
print 'Disconnection from %s:%s' % (ip, port)
listenSock = socket(AF_INET, SOCK_STREAM)
listenSock.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1)
listenSock.bind(('0.0.0.0', PORT))
listenSock.listen(20)
print 'Listening on port 49300...'
while True:
clientSock, (ip, port) = listenSock.accept()
Thread(target=SignalingChannel, args=(ip, port, clientSock)).start()
要运行代码,请启动信令服务器,在两个浏览器选项卡中打开网页,单击“创建数据通道”按钮,然后查看Web控制台.
任何想法?
解决方法:
查看Chrome / Firefox错误跟踪器,似乎已确定并解决了此问题,但仅在Chrome Canary 33.0.1715.0或更高版本中.
如果您不愿意使用上述的Chrome Canary版本,则可以检测到不良的对等体组合,并通过“要约”按钮向其他客户发出要约.
伪代码:
socket.onMessage(msg) {
if(msg == "request-offer"){
doOffer();
}
...
}
createDataChannelButton.onClick() {
if(!canCreateChannelBasedOnBrowser){
socket.send("request-offer");
}
else {
doOffer();
}
}
用您的示例代码:
<!DOCTYPE html>
<html>
<head>
<title>WebRTC test</title>
<meta charset="utf-8">
</head>
<body>
<button id="create" disabled>Create data channel</button>
<script type="text/javascript">
// DOM
// CHANGE: Add basic browser detection based on google's adapter.js file.
var rtcBrowserVersion = 0;
var rtcCanInitiateDataOffer = false;
if (navigator.mozGetUserMedia) {
rtcBrowserVersion = parseInt(navigator.userAgent.match(/Firefox\/([0-9]+)\./)[1], 10);
rtcCanInitiateDataOffer = true;
} else if (navigator.webkitGetUserMedia) {
// Chrome Canary reports major version 35 for me. Can't find a reliable resource to confirm
// canary versions.
rtcBrowserVersion = parseInt(navigator.userAgent.match(/Chrom(e|ium)\/([0-9]+)\./)[2], 10);
rtcCanInitiateDataOffer = rtcBrowserVersion >= 35;
}
var create = document.getElementById('create');
// Compatibility
window.RTCPeerConnection = window.RTCPeerConnection || window.mozRTCPeerConnection || window.webkitRTCPeerConnection;
window.RTCSessionDescription = window.RTCSessionDescription || window.mozRTCSessionDescription || window.webkitRTCSessionDescription;
window.RTCIceCandidate = window.RTCIceCandidate || window.mozRTCIceCandidate || window.webkitRTCIceCandidate;
// Create a WebRTC object
var rtc = new RTCPeerConnection(null);
// Create a data channel
var sendChannel = rtc.createDataChannel('pingtest', {reliable: false});
var myMsg = 'ping';
function setRecvChannel(recvChannel) {
recvChannel.onmessage = function(event) {
if(event.data.indexOf('\x03\x00\x00\x00\x00\x00\x00\x00\x00') === 0) {
console.log('-> ' + window.btoa(event.data));
return; // Received channel's name, ignore
}
console.log('-> ' + event.data);
window.setTimeout(function() {
console.log('<- ' + myMsg);
sendChannel.send(myMsg);
}, 500);
};
}
// Chrome and Firefox
sendChannel.onopen = function(event) {
setRecvChannel(sendChannel);
if(myMsg === 'ping') {
console.log('<- ' + myMsg);
sendChannel.send(myMsg);
}
};
// Firefox
rtc.ondatachannel = function(event) {
setRecvChannel(event.channel);
};
// ICE
rtc.onicecandidate = function(event) {
if(event.candidate) {
console.log('<- ' + JSON.stringify(event.candidate));
ws.send(JSON.stringify(event.candidate));
}
};
// Signaling channel
var ws = new WebSocket('ws://127.0.0.1:49300/');
ws.onopen = function() {
create.disabled = false;
};
ws.onmessage = function(event) {
console.log('-> ' + event.data);
var data = JSON.parse(event.data);
if(data.sdp) {
rtc.setRemoteDescription(new RTCSessionDescription(data));
if(data.type === 'offer') {
myMsg = 'pong';
rtc.createAnswer(function(anwser) {
rtc.setLocalDescription(anwser, function () {
console.log('<- ' + JSON.stringify(anwser));
ws.send(JSON.stringify(anwser));
});
}, console.error);
}
}
// CHANGE: Chrome with offer bug asked to initiate the offer.
else if(data.initiate === true){
doOffer();
}
else {
rtc.addIceCandidate(new RTCIceCandidate(data));
}
};
ws.onclose = function() {
create.disabled = true;
};
// Create an offer
// CHANGE: Create function for offer, so that it may be called from ws.onmessage
function doOffer(){
rtc.createOffer(function(offer) {
rtc.setLocalDescription(offer, function () {
offer.sdp = offer.sdp;
console.log(offer.sdp);
console.log('<- ' + JSON.stringify(offer));
ws.send(JSON.stringify(offer));
});
}, console.error);
}
create.onclick = function() {
// CHANGE: If this client is not able to negotiate a data channel, send a
// message to the peer asking them to offer the channel.
if(rtcCanInitiateDataOffer){
doOffer();
}
else {
ws.send(JSON.stringify({initiate:true}));
}
};
相关问题:
> WebRTC-Test SCTP data channel interop with Firefox固定关闭时间为11/25/13
>铬-SCTP Data Channel fails to connect if Chrome offers and FF answers-封闭时固定为11/4/13
还值得注意的是,当前将数据发送到Chrome对等端时会显示max message buffer size of 16KB.如果要发送大数据消息,则需要先将它们分成16KB的块,然后再通过数据通道进行传输.
内容总结
以上是互联网集市为您收集整理的javascript-Firefox启动连接时,无法在Chrome中使用WebRTC数据通道全部内容,希望文章能够帮你解决javascript-Firefox启动连接时,无法在Chrome中使用WebRTC数据通道所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。