我试图遵循this example by Dan Ristic进行RTCDataChannel
浏览器p2p通信,并与Google的Channel API进行信号传输。它似乎无声地失败了-我无法触发RTCDataChannel.onopen
,RTCPeerConnection.onicecandidate
或RTCPeerConnection.ondatachannel
事件。
客户端JS / HTML:
<html>
<head>
<script src="https://code.jquery.com/jquery-1.11.2.min.js"></script>
<script type="text/javascript" src="/_ah/channel/jsapi"></script>
<script>
$(document).ready(function(){
var IS_CHROME = !!window.webkitRTCPeerConnection,
RTCPeerConnection = window.webkitRTCPeerConnection || mozRTCPeerConnection,
RTCIceCandidate = window.RTCIceCandidate || RTCSessionDescription,
RTCSessionDescription = window.RTCSessionDescription || mozRTCSessionDescription,
SESSION_ID = "12345",
weAreHost,
optionalRtpDataChannels = {
optional: [{RtpDataChannels: true}]
},
mediaConstraints = {
optional: [],
mandatory: {
OfferToReceiveAudio: false, // Hmm!!
OfferToReceiveVideo: false // Hmm!!
}
};
// Signaling Channel Object
function SignalingChannel(peerConnection) {
// Setup the signaling channel here
this.peerConnection = peerConnection;
}
function setChannelEvents(dataChannel) {
dataChannel.onmessage = function (event) {
console.log("I got data channel message: ", event.data);
}
dataChannel.onopen = function (event) {
dataChannel.send("RTCDataChannel Open!");
}
dataChannel.error = function(event) {
console.log("data channel error:", event)
}
}
SignalingChannel.prototype.send = function(message) {
console.log("signal send:", message);
var url = "/api/signal/send/";
url += weAreHost ? "client"+SESSION_ID : "host"+SESSION_ID;
$.ajax({
type: "PUT",
url: url,
contentType: "application/json",
data: JSON.stringify(message)
});
};
SignalingChannel.prototype.onmessage = function(message) {
console.log("signal receive:", message);
// If we get a sdp we have to sign and return it
if (message.sdp != null) {
var that = this;
this.peerConnection.setRemoteDescription(new RTCSessionDescription(message), function () {
that.peerConnection.createAnswer(function (description) {
that.send(description);
}, null, mediaConstraints);
});
} else {
this.peerConnection.addIceCandidate(new RTCIceCandidate(message.candidate));
}
};
function initiateConnection(input) {
weAreHost = input;
// setup signaling mechanism with Google Channel API
var url = "/api/signal/init/";
url += weAreHost ? "host"+SESSION_ID : "client"+SESSION_ID;
$.post(url, "", function(response){
var channel = new goog.appengine.Channel(response.token);
var socket = channel.open();
socket.onerror = function(){console.log(arguments);};
socket.onclose = function(){console.log(arguments);};
var closeSocket = function() {
if(socket) return socket.close();
else return "google socket does not exist"
}
$(window).unload(closeSocket);
window.onbeforeunload = closeSocket;
socket.onopen = function() {
console.log("google socket opened");
// Create a peer connection object
var connection = new RTCPeerConnection({
iceServers: [
{ 'url': (IS_CHROME ? 'stun:stun.l.google.com:19302' : 'stun:23.21.150.121') }
]
}, optionalRtpDataChannels);
// Initiate a signaling channel between two users
var signalingChannel = new SignalingChannel(connection);
connection.onicecandidate = function (event) {
console.log("onicecandidate:", event);
if (!event || !event.candidate) return;
signalingChannel.send({candidate:event.candidate});
};
// Effectively set SignalingChannel as google channel socket inbound event handler
socket.onmessage = function(input) {
console.log("received from google:", input);
var message = $.parseJSON(input.data);
signalingChannel.onmessage(message);
};
// Only one client should initiate the connection, the other client should wait.
if(weAreHost) {
connection.ondatachannel = function(event) {
setChannelEvents(event.channel);
}
} else {
// Create client RTCDataChannel
var clientChannel = connection.createDataChannel("my_label", {reliable: false});
setChannelEvents(clientChannel);
connection.createOffer(function (description) {
signalingChannel.send(description);
}, function(error){
console.log(error);
}, mediaConstraints);
}
};
}, "json");
};
// Create a button on the page so only one client initiates the connection.
$("#i-am-host").click(function() {
initiateConnection(true);
});
$("#i-am-client").click(function() {
initiateConnection(false);
});
});
</script>
</head>
<body>
<p id="i-am-host" style="background-color: green;">I AM HOST</p>
<p id="i-am-client" style="background-color: blue;">I AM CLIENT</p>
</body>
</html>
App Engine Python:
from google.appengine.api import channel
from django.shortcuts import render
from django.http import HttpResponse
import json
def init(request, browser_id):
token = channel.create_channel(browser_id);
return HttpResponse(json.dumps({'token':token}))
def send(request, browser_id):
channel.send_message(browser_id, request.body)
return HttpResponse()
浏览器控制台:
[HOST]
received from google:
Object {data: "{"sdp":"v=0\r\no=- 6804947085651458452 2 IN IP4 12…5000 webrtc-datachannel 1024\r\n","type":"offer"}"}
test.html:34
signal receive:
Object {sdp: "v=0
↵o=- 6804947085651458452 2 IN IP4 127.0.0.1
↵s…id:data
↵a=sctpmap:5000 webrtc-datachannel 1024
↵", type: "offer"}
test.html:22
signal send:
RTCSessionDescription {sdp: "v=0
↵o=- 600524556593905006 2 IN IP4 127.0.0.1
↵s=…id:data
↵a=sctpmap:5000 webrtc-datachannel 1024
↵", type: "answer"}
[CLIENT]
signal send:
RTCSessionDescription {sdp: "v=0
↵o=- 6804947085651458452 2 IN IP4 127.0.0.1
↵s…id:data
↵a=sctpmap:5000 webrtc-datachannel 1024
↵", type: "offer"}
test.html:82
received from google:
Object {data: "{"sdp":"v=0\r\no=- 600524556593905006 2 IN IP4 127…000 webrtc-datachannel 1024\r\n","type":"answer"}"}
test.html:34
signal receive: Object {sdp: "v=0
↵o=- 600524556593905006 2 IN IP4 127.0.0.1
↵s=…id:data
↵a=sctpmap:5000 webrtc-datachannel 1024
↵", type: "answer"}
最佳答案
Firefox不(永远不会)支持RtpDataChannels。它仅支持符合规范(和更高级)的SCTP数据通道。删除可选约束将使您切换到它们,而无需其他更改。
您的SDP中似乎包含sctp行有点奇怪。 http://googlechrome.github.io/webrtc/samples/web/content/datachannel/处的google示例
使用rtp数据通道时不起作用。