Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/google-app-engine/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 带有Google通道API的RTCDataChannel_Javascript_Google App Engine_Webrtc_Channel Api_Rtcdatachannel - Fatal编程技术网

Javascript 带有Google通道API的RTCDataChannel

Javascript 带有Google通道API的RTCDataChannel,javascript,google-app-engine,webrtc,channel-api,rtcdatachannel,Javascript,Google App Engine,Webrtc,Channel Api,Rtcdatachannel,我正试图通过谷歌的p2p通信来进行RTCDataChannel浏览器的信令。它似乎在无声地失败-我无法触发RTCDataChannel.onopen、RTCPeerConnection.onicecandidate、或RTCPeerConnection.ondatachannel事件 客户端JS/HTML: 浏览器控制台: 首先,在数据通道创建的另一端缺少peerConnection.onDataChannel 代码类似于: answerer.ondatachannel = function (

我正试图通过谷歌的p2p通信来进行
RTCDataChannel
浏览器的信令。它似乎在无声地失败-我无法触发
RTCDataChannel.onopen
RTCPeerConnection.onicecandidate
、或
RTCPeerConnection.ondatachannel
事件

客户端JS/HTML: 浏览器控制台:
首先,在数据通道创建的另一端缺少
peerConnection.onDataChannel

代码类似于:

answerer.ondatachannel = function (event) {
        answererDataChannel = event.channel;
        answererDataChannel.binaryType = 'blob';
        setChannelEvents(answererDataChannel, 'answerer');
    };

...


function setChannelEvents(channel, channelNameForConsoleOutput) {
    channel.onmessage = function (event) {
        console.debug(channelNameForConsoleOutput, 'received a message:', event.data);
    };
    channel.onopen = function () {
        channel.send('first text message over SCTP data ports');
    };
}

对于完整的代码,您可以检查此

对于初学者,您缺少数据通道创建另一侧的
peerConnection.onDataChannel

代码类似于:

answerer.ondatachannel = function (event) {
        answererDataChannel = event.channel;
        answererDataChannel.binaryType = 'blob';
        setChannelEvents(answererDataChannel, 'answerer');
    };

...


function setChannelEvents(channel, channelNameForConsoleOutput) {
    channel.onmessage = function (event) {
        console.debug(channelNameForConsoleOutput, 'received a message:', event.data);
    };
    channel.onopen = function () {
        channel.send('first text message over SCTP data ports');
    };
}

对于完整的代码,您可以检查这个

经过几个小时的尝试,我能够让我的原始示例在Chrome 40.0.2214.93和Opera 27.0上运行(最新版本)。帮助很大。我没能在Firefox上运行它:

<html>
<head>
<script src="https://code.jquery.com/jquery-2.1.3.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 = "123456",
            weAreHost,
            optionalRtpDataChannels = {
                optional: [{RtpDataChannels: true}]
            },
            mediaConstraints = {
                    optional: [],
                    mandatory: {
                        OfferToReceiveAudio: false,
                        OfferToReceiveVideo: false
                    }
                };

        // 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("######### SUCCESS ######### RTCDataChannel Open!");
            }

            dataChannel.error = function(event) {
                console.log("data channel error:", event)
            }
        }

        function error(e) {
            console.log(arguments);
            throw new Error(e);
        }

        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);          
            var self = this;

            if(message.type && message.type === "offer") {
                var offer = new RTCSessionDescription(message);
                this.peerConnection.setRemoteDescription(offer, function() {
                    self.peerConnection.createAnswer(function(answer) {
                        self.peerConnection.setLocalDescription(answer, function() {
                            self.send(answer);
                        }, error);
                    }, error, mediaConstraints);
                });
            } else if(message.type && message.type === "answer") {
                var answer = new RTCSessionDescription(message);
                this.peerConnection.setRemoteDescription(answer, function(){            
                }, error);
            } 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 = error;

                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);

                        // create offer and send to host
                        connection.createOffer(function (offer) {                           
                            connection.setLocalDescription(offer, function() {                          
                                signalingChannel.send(offer);
                            }, error);
                        }, error, mediaConstraints);
                    }           
                };
            }, "json").fail(error);
        };

        // 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>
    <br>
    <p id="print">PRINT SIGNALING STATE<p>
</body>
</html>

$(文档).ready(函数(){
变量为_CHROME=!!window.webkirtpeerconnection,
RTPEERCONNECTION=window.webkitRTPEERCONNECTION | | mozRTPEERCONNECTION,
RTCIceCandidate=window.RTCIceCandidate | | RTCSessionDescription,
RTCSessionDescription=window.RTCSessionDescription | | mozRTCSessionDescription,
SESSION_ID=“123456”,
weAreHost,
可选RTPDataChannel={
可选:[{RtpDataChannels:true}]
},
媒体约束={
可选:[],
强制性:{
OfferToReceiveAudio:false,
OfferToReceiveVideo:错误
}
};
//信令信道对象
功能信号通道(对等连接){
//在这里设置信令通道
this.peerConnection=peerConnection;
}
函数setChannelEvents(数据通道){
dataChannel.onmessage=函数(事件){
log(“我得到了数据通道消息:”,event.data);
}
dataChannel.onopen=函数(事件){
数据频道。发送(“数据频道开放!”);
}
dataChannel.error=函数(事件){
日志(“数据通道错误:”,事件)
}
}
函数错误(e){
log(参数);
抛出新错误(e);
}
SignalingChannel.prototype.send=函数(消息){
//控制台日志(“信号发送:”,消息);
var url=“/api/signal/send/”;
url+=weAreHost?“客户端”+会话ID:“主机”+会话ID;
$.ajax({
键入:“放置”,
url:url,
contentType:“应用程序/json”,
数据:JSON.stringify(消息)
});
};
SignalingChannel.prototype.onmessage=函数(消息){
//控制台日志(“信号接收:”,消息);
var self=这个;
if(message.type&&message.type==“offer”){
var offer=新的RTCSessionDescription(消息);
this.peerConnection.setRemoteDescription(提供,函数(){
self.peerConnection.createAnswer(函数(应答){
self.peerConnection.setLocalDescription(应答,函数(){
发送(应答);
},错误);
},错误,限制);
});
}else if(message.type&&message.type==“应答”){
var answer=新的RTCSessionDescription(消息);
this.peerConnection.setRemoteDescription(应答,函数(){
},错误);
}否则{
this.peerConnection.addIceCandidate(新的RTCIceCandidate(message.candidate));
}
};
功能启动连接(输入){
weAreHost=输入;
//用googlechannelapi设置信令机制
var url=“/api/signal/init/”;
url+=weAreHost?“主机”+会话ID:“客户端”+会话ID;
$.post(url,“),函数(响应){
var channel=new goog.appengine.channel(response.token);
var socket=channel.open();
socket.onerror=错误;
var closeSocket=函数(){
if(socket)返回socket.close();
否则返回“google套接字不存在”
}
$(窗口)。卸载(closeSocket);
window.onbeforeunload=closeSocket;
socket.onopen=函数(){
log(“谷歌套接字打开”);
//创建对等连接对象
var连接=新的RTPEERCONNECTION({
ICEServer:[
{'url':(是CHROME吗?'stun:stun.l.google.com:19302':'stun:23.21.150.121'))
]
},可选RTPDataChannel);
//启动两个用户之间的信令通道
var信号通道=新信号通道(连接);
connection.onicecandidate=函数(事件){
//console.log(“onicecandidate:,事件”);
如果(!event | |!event.candidate)返回;
send({candidate:event.candidate});
};
//有效地将SignalingChannel设置为google通道套接字入站事件处理程序
socket.onmessage=函数(输入){
//log(“从google接收:”,输入);
var message=$.parseJS
answerer.ondatachannel = function (event) {
        answererDataChannel = event.channel;
        answererDataChannel.binaryType = 'blob';
        setChannelEvents(answererDataChannel, 'answerer');
    };

...


function setChannelEvents(channel, channelNameForConsoleOutput) {
    channel.onmessage = function (event) {
        console.debug(channelNameForConsoleOutput, 'received a message:', event.data);
    };
    channel.onopen = function () {
        channel.send('first text message over SCTP data ports');
    };
}
<html>
<head>
<script src="https://code.jquery.com/jquery-2.1.3.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 = "123456",
            weAreHost,
            optionalRtpDataChannels = {
                optional: [{RtpDataChannels: true}]
            },
            mediaConstraints = {
                    optional: [],
                    mandatory: {
                        OfferToReceiveAudio: false,
                        OfferToReceiveVideo: false
                    }
                };

        // 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("######### SUCCESS ######### RTCDataChannel Open!");
            }

            dataChannel.error = function(event) {
                console.log("data channel error:", event)
            }
        }

        function error(e) {
            console.log(arguments);
            throw new Error(e);
        }

        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);          
            var self = this;

            if(message.type && message.type === "offer") {
                var offer = new RTCSessionDescription(message);
                this.peerConnection.setRemoteDescription(offer, function() {
                    self.peerConnection.createAnswer(function(answer) {
                        self.peerConnection.setLocalDescription(answer, function() {
                            self.send(answer);
                        }, error);
                    }, error, mediaConstraints);
                });
            } else if(message.type && message.type === "answer") {
                var answer = new RTCSessionDescription(message);
                this.peerConnection.setRemoteDescription(answer, function(){            
                }, error);
            } 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 = error;

                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);

                        // create offer and send to host
                        connection.createOffer(function (offer) {                           
                            connection.setLocalDescription(offer, function() {                          
                                signalingChannel.send(offer);
                            }, error);
                        }, error, mediaConstraints);
                    }           
                };
            }, "json").fail(error);
        };

        // 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>
    <br>
    <p id="print">PRINT SIGNALING STATE<p>
</body>
</html>
<html>
<head>
<script src="https://code.jquery.com/jquery-2.1.3.min.js"></script>
<script src="http://cdn.peerjs.com/0.3.9/peer.js"></script>
<script>
    $(document).ready(function(){

        var SESSION_ID = "1234";

        // Create a button on the page so only one client initiates the connection.         
        $("#i-am-host").click(function() {

            var host = new Peer('host'+SESSION_ID, {host: 'my-peerjs.herokuapp.com', port: 80});
            host.on("connection", function(conn) {
                conn.on('data', function(data) {
                    console.log(data);
                });
            });

        });
        $("#i-am-client").click(function() {

            var client = new Peer('client'+SESSION_ID, {host: 'my-peerjs.herokuapp.com', port: 80});
            var conn = client.connect('host'+SESSION_ID);
            conn.on("open", function(){
                conn.send("SUCCESS!!");
            });     
        });
    });
</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>