Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/html/76.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 WebRTC iceConnectionState仍处于';检查';状态_Javascript_Html_Websocket_Webrtc_Stun - Fatal编程技术网

Javascript WebRTC iceConnectionState仍处于';检查';状态

Javascript WebRTC iceConnectionState仍处于';检查';状态,javascript,html,websocket,webrtc,stun,Javascript,Html,Websocket,Webrtc,Stun,我想创建一个简单的视频聊天应用程序。我在Node.js中使用WebRTC和WebSocket。我想连接同一网络中的两个设备,但iceConnectionState始终处于“检查”状态。有什么问题吗 编辑 server.js //var uuid = require('uuid'); var fs = require('fs'); var webSocketServer = require('websocket').server; var cfg = { ssl: false,

我想创建一个简单的视频聊天应用程序。我在Node.js中使用WebRTC和WebSocket。我想连接同一网络中的两个设备,但iceConnectionState始终处于“检查”状态。有什么问题吗

编辑 server.js

//var uuid = require('uuid');

var fs = require('fs');
var webSocketServer = require('websocket').server;

var cfg = {
    ssl: false,
    port: 15555,
    ssl_key: '/etc/apache2/ssl/apache.key',
    ssl_cert: '/etc/apache2/ssl/apache.crt'
};

var httpServer = (cfg.ssl) ? require('https') : require('http');

var server = null;

if(cfg.ssl) {
    server = httpServer.createServer(
        {
            key: fs.readFileSync(cfg.ssl_key),
            cert: fs.readFileSync(cfg.ssl_cert)
        }, function() {} ).listen(cfg.port);
} else {
    server = httpServer.createServer().listen(cfg.port);
}

var wsServer = new webSocketServer({
    httpServer: server
});

rooms = {};

// this is executed each time the websocket
// server receives an request
wsServer.on('request', function(request) {

    // allow all incoming connections
    var connection = request.accept(null, request.origin);


    // here we read the incoming messages and try to parse them to JSON
    connection.on('message', function(message) {
        // try to parse JSON
        try {
            var data = JSON.parse(message.utf8Data);
        } catch (e) {
            console.log('This does not look like valid JSON');
        }

        // if JSON is valid process the request
        if (data !== undefined && data.type !== undefined) {
            switch (data.type) {
                case 'createRoom':
                    var roomName = data.roomName;
                    console.log('CREATE_ROOM request received');

                    rooms[roomName] = {
                        creatorConnection: connection,
                        partnerConnection: false,
                    }

                    var data = {
                        type: 'roomCreated',
                        payload: roomName
                    };
                    return send(rooms[roomName].creatorConnection, data);
                    break;
                case 'offer':
                    console.log('OFFER received from client');

                    if (rooms[data.roomName].partnerConnection) {
                        // send error to user
                        var data = {
                            type: 'error',
                            payload: 'room is already full'
                        };
                        return send(connection, data);
                    }
                    rooms[data.roomName].partnerConnection = this;

                    console.log('OFFER send to host');
                    return send(rooms[data.roomName].creatorConnection, data);
                    break;
                    // send to other guy
                default:
                    if (this === rooms[data.roomName].partnerConnection) {
                        console.log('send to creator : ' + data.type);
                        return send(rooms[data.roomName].creatorConnection, data);
                    }
                    console.log('send to parther : ' + data.type);
                    return send(rooms[data.roomName].partnerConnection, data);
                    break;
            }
        }
        // if JSON is invalid or type is missing send error
        else {
            var data = {
                type: 'error',
                payload: 'ERROR FROM SERVER: Incorrect data or no data received'
            };
            send(connection, data);
        }
    });

    // this function sends data to the other user
    var send = function(connection, data) {
        try {
            connection.sendUTF(JSON.stringify(data));
        } catch (e) {
            console.log('\n\n!!!### ERROR while sending message ###!!!\n');
            console.log(e + '\n');
            return;
        }
    };
});
client.js

function WebRTC() {

    var wsServer = false;
    var localStream = false;
    var remoteStream = false;
    var peerConnection = false;
    var roomName = null;
    var otherSDP = false;
    var othersCandidates = []; // other guy's icecandidates

    var socketEvent = document.createEvent('Event');
    socketEvent.initEvent('socketEvent', true, true);

    var mediaConstraints = {
        audio: true,
        video: true
    };

    var peerConnectionConfig = {
        iceServers: [
            {url : 'stun:stun.l.google.com:19302'},
            {url : 'stun:stun.anyfirewall.com:3478'},
            {url : 'turn:turn.bistri.com:80',
                credential: 'homeo',
                username: 'homeo'},
            {url : 'turn:turn.anyfirewall.com:443?transport=tcp',
                credential: 'webrtc',
                username: 'webrtc'}
        ]
    };

    var offerAnswerConstraints = { mandatory: {
        OfferToReceiveAudio: true,
        OfferToReceiveVideo: true
    }};

    var sendToServer = function(data) {
        try {
            wsServer.send(JSON.stringify(data));
            return true;
        } catch (e) {
            logError(e);
            return false;
        }
    };

    var createRTCIceCandidate = function(candidate) {
        var iceCandidate;

        debug(candidate);
        debug(JSON.parse(candidate));

        if (typeof(webkitRTCIceCandidate) === 'function') {
            iceCandidate = new webkitRTCIceCandidate(candidate);
        } if (typeof(mozRTCIceCandidate) === 'function') {
            iceCandidate = new mozRTCIceCandidate((candidate));
        } else if (typeof(RTCIceCandidate) === 'function') {
            iceCandidate = new RTCIceCandidate(candidate);
        }

        return iceCandidate;
    };

    var createRTCSessionDescription = function(description) {
        var newSdp;

        if (typeof(RTCSessionDescription) === 'function') {
            newSdp = new RTCSessionDescription(description);
        } else if (typeof(webkitRTCSessionDescription) === 'function') {
            newSdp = new webkitRTCSessionDescription(description);
        } else if (typeof(mozRTCSessionDescription) === 'function') {
            newSdp = new mozRTCSessionDescription(description);
        }

        return newSdp;
    };

    var getRTCPeerConnection = function(stream) {
        var peerConnection = null;

        if (typeof(RTCPeerConnection) === 'function') {
            peerConnection = new RTCPeerConnection(peerConnectionConfig);
        } else if (typeof(webkitRTCPeerConnection) === 'function') {
            peerConnection = new webkitRTCPeerConnection(peerConnectionConfig);
        } else if (typeof(mozRTCPeerConnection) === 'function') {
            peerConnection = new mozRTCPeerConnection(peerConnectionConfig);
        }

        debug("Creating new RTCPeerConnection");

        peerConnection.addStream(stream);

        peerConnection.onaddstream = function(e) {
            debug("Remote stream received");

            remoteStream = e.stream;

            socketEvent.eventType = 'streamAdded';
            document.dispatchEvent(socketEvent);
        };

        peerConnection.onicecandidate = function(event) {
            debug("Retrieving ICE data status changed : " + event.target.iceGatheringState)

            var data = {
                type: 'iceCandidate',
                roomName: roomName,
                payload: event
            };

            sendToServer(data);
        };

        peerConnection.oniceconnectionstatechange = function(event) {
            debug("ICE connection status changed : " + event.target.iceConnectionState)
        };

        return peerConnection;
    };

    var setIceCandidates = function(iceCandidate) {
        // push icecandidate to array if no SDP of other guys is available
        if (!otherSDP) {
            othersCandidates.push(iceCandidate);
        }
        // add icecandidates immediately if not Firefox & if remoteDescription is set
        if (otherSDP && iceCandidate.candidate && iceCandidate.candidate !== null) {
            peerConnection.addIceCandidate(createRTCIceCandidate(iceCandidate.candidate));
        }
    };

    var handshakeDone = function() {
        console.log('handshakeDone');
        peerConnection.setRemoteDescription(createRTCSessionDescription(otherSDP), function() {
            // add other guy's ice-candidates to connection
            for (var i = 0; i < othersCandidates.length; i++) {
                if (othersCandidates[i].candidate) {
                    peerConnection.addIceCandidate(ceateRTCIceCandidate(othersCandidates[i].candidate));
                }
            }
            // fire event
            socketEvent.eventType = 'p2pConnectionReady';
            document.dispatchEvent(socketEvent);
        }, logError);

    };

    var createOffer = function() {
        peerConnection = getRTCPeerConnection(localStream);

        debug('Offer creating');
        peerConnection.createOffer(function(description) {
            debug('Offer created');
            debug('Local description setting');

            peerConnection.setLocalDescription(description, function() {
                debug('Local description set');
                var data = {
                    type: 'offer',
                    roomName: roomName,
                    payload: description
                };

                sendToServer(data);
            }, logError);
        }, logError);
    };

    var createAnswer = function() {
        peerConnection = getRTCPeerConnection(localStream);

        debug('Offer answering');
        debug('Remote description setting');

        peerConnection.setRemoteDescription(createRTCSessionDescription(otherSDP), function () {
            debug('Remote description set');
            debug('Answer creating');

            peerConnection.createAnswer(function(description) {
                debug('Answer created');
                debug('Local description setting');

                peerConnection.setLocalDescription(description, function() {
                    debug('Local description set');

                    for (var i = 0; i < othersCandidates.length; i++) {
                        if (othersCandidates[i].candidate) {
                            peerConnection.addIceCandidate(ceateRTCIceCandidate(othersCandidates[i].candidate));
                        }
                    }

                    // send SDP to other guy
                    var data = {
                        type: 'answer',
                        roomName: roomName,
                        payload: description
                    };

                    sendToServer(data);
                }, logError);
            }, logError);
        }, logError);
    };

    this.connectToSocket = function(wsUrl) {
        wsServer = new WebSocket(wsUrl);

        wsServer.onopen = function(event) {
            console.log((new Date()) + ' Connection successfully established');
        };

        wsServer.onerror = function(e) {
            console.log((new Date()) + ' WebSocket connection error: ');
            logError(e);
        };

        wsServer.onclose = function(event) {
            console.log((new Date()) + ' Connection was closed');
            logError(e);
        };

        wsServer.onmessage = function(message) {
            try {
                var data = JSON.parse(message.data);
            } catch (e) {
                logError(e);
                return;
            }

            switch (data.type) {
                case 'roomCreated':
                    roomName = data.payload;
                    socketEvent.eventType = 'roomCreated';
                    document.dispatchEvent(socketEvent);
                    break;
                case 'offer':
                    otherSDP = data.payload;
                    createAnswer();
                    break;
                case 'answer':
                    otherSDP = data.payload;
                    handshakeDone();
                    break;
                case 'iceCandidate':
                    setIceCandidates(data.payload);
                    break;
            }
        };
    };

    this.getRoomName = function() {
        return roomName;
    };

    this.createRoom = function(roomName) {
        var media = getMedia();

        var onSuccess = function(stream) {
            localVideo.attr('src', URL.createObjectURL(stream));
            localStream = stream;

            var data = {
                type: 'createRoom',
                roomName: roomName,
                payload: false
            };

            return sendToServer(data)
        };

        media(mediaConstraints, onSuccess, logError);
    };

    this.joinRoom = function(rName) {
        var media = getMedia();

        var onSuccess = function(stream) {
            localVideo.attr('src', URL.createObjectURL(stream));
            localStream = stream;
            //TODO
            roomName = rName;

            createOffer();
        };

        media(mediaConstraints, onSuccess, logError);
    };


    var getMedia = function() {
        var media = null;

        if (navigator.getUserMedia) {;
            media = navigator.getUserMedia.bind(navigator);
        } else if (navigator.webkitGetUserMedia) {
            media = navigator.webkitGetUserMedia.bind(navigator);
        } else if (navigator.mozGetUserMedia) {
            media = navigator.mozGetUserMedia.bind(navigator);
        }

        return media;
    };

    // get the other guys media stream
    this.getRemoteStream = function() {
        return remoteStream;
    };

}
common.js

function debug(message) {
    console.log(message);
}

function logError(e) {
    console.error(e);
}
index.html

<!doctype html> 
<html>
    <head>
        <title>WebRTC</title>
        <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
        <meta content="text/html;charset=utf-8" http-equiv="Content-Type">
<meta content="utf-8" http-equiv="encoding">
        <link href="css/bootstrap.css" rel="stylesheet">
    </head>
    <body style="padding: 5em;">
        <section id="loginSection">
            <div class="row" style="margin-bottom: 2em;">
                <div clsss="col-xs-12">
                    <button id="createRoomButton" type="button" class="btn btn-default btn-lg center-block">
                      Create room
                    </button>
                </div>
            </div>
            <div class="row" style="margin-bottom: 4em;">
                <div clsss="col-xs-12">
                    <button id="joinRoomButton" type="button" class="btn btn-default btn-lg center-block">
                      Join room
                    </button>
                </div>
            </div>
            
            <div class="row">
                <div clsss="col-xs-4">
                    <input id="roomNameInput" type="text" style="width: 200px;" class="form-control center-block" 
                           placeholder="Room's name" aria-describedby="basic-addon2">
                </div>
            </div>
        </section>
        
        <section id="roomSection" style="display: none;">
            <h3>
                Room's name: 
                <span id="roomNameField" style="font-weight: bold;"></span>
            </h3>
            <div class="video-wrapper">
                <video id="remoteVideo" autoplay="true"></video>
                <video id="localVideo"  autoplay="true" muted="true" width="200" height="200"></video>
            </div>
        </section>
        
        <script src="js/jquery-2.1.4.js" type="text/javascript"></script>
        <script src="js/bootstrap.js" type="text/javascript"></script>
        <script src="js/common.js" type="text/javascript"></script>
        <script src="js/client.js" type="text/javascript"></script>
        <script src="js/main.js" type="text/javascript"></script>
    </body>
</html>

WebRTC
创造空间
会客室
房间名称:

对于Mozilla vs.Chrome,您可能仍然需要对此进行填充,但问题似乎是您试图通过WebSocket发送
RTICeCandidateEvent
,而不仅仅是
RTICeCandidate
,而且它没有通过套接字

我试过这个:

peerConnection.onicecandidate = function(event) {
    debug("Retrieving ICE data status changed : " + event.target.iceGatheringState)
    console.log(event);
    console.log(event.candidate);
    if(event.candidate) {
        var data = {
            type: 'iceCandidate',
            roomName: roomName,
            payload: event.candidate
        };
        sendToServer(data);
    }
};
然后在您的
wsServer.onmessage
将其传递给
setIceCandidates
后,将其添加到另一端(但正如我所说,您可能需要为Firefox填充):

我建议在
peerConnection.onicecandidate
中过滤掉发送方端的
未定义的
候选ICE
,而不是在接收端的
设置候选ICE
中。另外,我认为您不需要将
ICE候选
存储在
othersCandidates
数组中,然后再添加它们。在我的版本中,我从来没有这样做过。
iceCandidate
的东西似乎自动化程度很好,不需要额外的帮助。(如果你知道这样做的好处,请告诉我。)


另一方面,使用
debug
函数来执行
console.log()
,会更紧凑一些,但它会替换提供错误源的行号

html在哪里?我愿意测试和调试WebRTC的东西,但我不想在开始之前编写html以适应您的JavaScript。(特别是如果你已经写了!)我添加了html并编辑了其他文件。它只适用于Firefox 28和Android版谷歌Chrome的本地网络。我还有一个问题。我想在一个房间里为许多用户实现视频聊天。我有两个选择:星形拓扑和网状拓扑。在我看来,网格拓扑是最容易实现的,但是对于一个房间中的许多用户来说,它可能太慢了。我更喜欢星型拓扑。我正在寻找库/框架,帮助我实现代理服务器,在用户之间传输数据。我发现了
licode
,但我认为这是一个高层次的框架,因为我为我的工程论文创建了这个应用程序,这并不容易……对不起,我对这两个方面都没有任何经验。
peerConnection.onicecandidate = function(event) {
    debug("Retrieving ICE data status changed : " + event.target.iceGatheringState)
    console.log(event);
    console.log(event.candidate);
    if(event.candidate) {
        var data = {
            type: 'iceCandidate',
            roomName: roomName,
            payload: event.candidate
        };
        sendToServer(data);
    }
};
var setIceCandidates = function(iceCandidate) {
    peerConnection.addIceCandidate(new RTCIceCandidate(iceCandidate));

};