node.js - socket.io, webrtc, nodejs video chat app getting errors over https: ERR_SSL_PROTOCOL_ERROR, 404 (Not Found), and ERR_CONNECTION_TIMED_OUT -
i have put video chat app using socket.io, webrtc, nodejs online tutorial github getting errors when converting used on https:
request url:https://telemed.caduceususa.com/socket.io/?eio=3&transport=polling&t=1479396416422-0 request method:get status code:404 not found remote address:10.9.2.169:443
other errors have gotten in process follows:
when try declare different port - err_ssl_protocol_error,
when try declare port 80 or 8080 get: err_connection_timed_out
something going wrong on line inside socket.io.js:
xhr.send(this.data);
i running node.js server on windows server 2012 , have set iis serve server on port 80. have created subdomain https://telemed.caduceususa.com in dns , have purchased trusted ssl cert run site on https.
here excerpt of code dev tools contains above line causing error other code:
/** * creates xhr object , sends request. * * @api private */ request.prototype.create = function(){ var opts = { agent: this.agent, xdomain: this.xd, xscheme: this.xs, enablesxdr: this.enablesxdr }; // ssl options node.js client opts.pfx = this.pfx; opts.key = this.key; opts.passphrase = this.passphrase; opts.cert = this.cert; opts.ca = this.ca; opts.ciphers = this.ciphers; opts.rejectunauthorized = this.rejectunauthorized; var xhr = this.xhr = new xmlhttprequest(opts); var self = this; try { debug('xhr open %s: %s', this.method, this.uri); xhr.open(this.method, this.uri, this.async); if (this.supportsbinary) { // has done after open because firefox stupid // https://stackoverflow.com/questions/13216903/get-binary-data-with-xmlhttprequest-in-a-firefox-extension xhr.responsetype = 'arraybuffer'; } if ('post' == this.method) { try { if (this.isbinary) { xhr.setrequestheader('content-type', 'application/octet-stream'); } else { xhr.setrequestheader('content-type', 'text/plain;charset=utf-8'); } } catch (e) {} } // ie6 check if ('withcredentials' in xhr) { xhr.withcredentials = true; } if (this.hasxdr()) { xhr.onload = function(){ self.onload(); }; xhr.onerror = function(){ self.onerror(xhr.responsetext); }; } else { xhr.onreadystatechange = function(){ if (4 != xhr.readystate) return; if (200 == xhr.status || 1223 == xhr.status) { self.onload(); } else { // make sure `error` event handler that's user-set // not throw in same tick , gets caught here settimeout(function(){ self.onerror(xhr.status); }, 0); } }; } debug('xhr data %s', this.data); xhr.send(this.data); }
here server.js file:
var fs = require('fs'); var hskey = fs.readfilesync('ssl/telemed_internal_server.key'); var hscert = fs.readfilesync('ssl/telemed_internal_cert.pem'); var ca = fs.readfilesync('ssl/telemed_internal_key.pem'); var credentials = { ca: ca, key: hskey, cert: hscert }; var static = require('node-static'); var https = require('https'); var util = require('util'); var file = new(static.server)(); var app = https.createserver(credentials, function (req, res) { file.serve(req, res); }).listen(process.env.port || 80); var io = require('socket.io').listen(app); io.sockets.on('connection', function (socket){ // convenience function log server messages on client function log(){ var array = [">>> message server: "]; (var = 0; < arguments.length; i++) { array.push(arguments[i]); } socket.emit('log', array); } // when receive sdp, broadcast sdp other user socket.on('sdp', function(data){ console.log('received sdp ' + socket.id); socket.to(data.room).emit('sdp received', data.sdp); }); // when receive ice candidate, broadcast sdp other user socket.on('ice candidate', function(data){ console.log('received ice candidate ' + socket.id + ' ' + data.candidate); socket.to(data.room).emit('ice candidate received', data.candidate); }); socket.on('message', function (message) { log('got message:', message); // real app, room (not broadcast) socket.broadcast.emit('message', message); }); socket.on('create or join', function (room) { // join room var existingroom = io.sockets.adapter.rooms[room]; var clients = []; if(existingroom){ clients = object.keys(existingroom); } if(clients.length == 0){ socket.join(room); io.to(room).emit('empty', room); } else if(clients.length == 1){ socket.join(room); socket.to(room).emit('joined', room, clients.length + 1); } // allow 2 users max per room else{ socket.emit('full', room); } }); socket.on('error', function(error){ console.error(error); }) });
here main.js (config) file:
//my signalling server var serverip = "https://telemed.caduceususa.com/"; // rtcpeerconnection options var server = { // uses google's stun server iceservers: [{ "url": "stun:stun4.l.google.com:19302" }, { url: 'turn:numb.viagenie.ca', credential: 'muazkh', username: 'webrtc@live.com' }] }; // various other development ips // var serverip = "https://192.168.43.241:2013"; // var serverip = "https://10.0.11.196:2013"; var localpeerconnection, signallingserver; var btnsend = document.getelementbyid('btn-send'); var btnvideostop = document.getelementbyid('btn-video-stop'); var btnvideostart = document.getelementbyid('btn-video-start'); var btnvideojoin = document.getelementbyid('btn-video-join'); var localvideo = document.getelementbyid('local-video'); var remotevideo = document.getelementbyid('remote-video'); var inputroomname = document.getelementbyid('room-name'); var localstream, localiscaller; btnvideostop.onclick = function(e) { e.preventdefault(); // stop video stream if (localstream != null) { localstream.stop(); } // kill connections if (localpeerconnection != null) { localpeerconnection.removestream(localstream); localpeerconnection.close(); signallingserver.close(); localvideo.src = ""; remotevideo.src = ""; } btnvideostart.disabled = false; btnvideojoin.disabled = false; btnvideostop.disabled = true; } btnvideostart.onclick = function(e) { e.preventdefault(); // starting call localiscaller = true; initconnection(); } btnvideojoin.onclick = function(e) { e.preventdefault(); // joining call, not offering localiscaller = false; initconnection(); } function initconnection() { var room = inputroomname.value; if (room == undefined || room.length <= 0) { alert('please enter room name'); return; } // start connection! connect(room); btnvideostart.disabled = true; btnvideojoin.disabled = true; btnvideostop.disabled = false; } // webrtc stuff starts here // set objects prefixed window.rtcpeerconnection = window.rtcpeerconnection || window.mozrtcpeerconnection || window.webkitrtcpeerconnection || window.msrtcpeerconnection; window.rtcsessiondescription = window.rtcsessiondescription || window.mozrtcsessiondescription || window.webkitrtcsessiondescription || window.msrtcsessiondescription; navigator.getusermedia = navigator.getusermedia || navigator.mozgetusermedia || navigator.webkitgetusermedia || navigator.msgetusermedia; window.signallingserver = window.signallingserver; var sdpconstraints = { optional: [], mandatory: { offertoreceivevideo: true, } } function connect(room) { // create peer connection localpeerconnection = new rtcpeerconnection(server); // create local data channel, send remote navigator.getusermedia({ video: true, audio: true }, function(stream) { // , save local stream trace('got stream, saving , starting rtc conn'); // must add before calling setremotedescription() because // triggers 'addstream' event localpeerconnection.addstream(stream); localstream = stream; // show local video localvideo.src = window.url.createobjecturl(stream); // can start once have gotten local video establishrtcconnection(room); }, errorhandler) } function establishrtcconnection(room) { // create signalling server signallingserver = new signallingserver(room, serverip); signallingserver.connect(); // remote peer has joined room, initiate sdp exchange signallingserver.onguestjoined = function() { trace('guest joined!') // set local description , send remote localpeerconnection.createoffer(function(sessiondescription) { trace('set local session desc offer'); localpeerconnection.setlocaldescription(sessiondescription); // send local sdp remote signallingserver.sendsdp(sessiondescription); }); } // got sdp remote signallingserver.onreceivesdp = function(sdp) { // stream again localpeerconnection.addstream(localstream); trace(localstream) // if local caller, set remote desc if (localiscaller) { trace('is caller'); trace('set remote session desc answer'); localpeerconnection.setremotedescription(new rtcsessiondescription( sdp)); } // if local joining call, set remote sdp , create answer else { trace('set remote session desc offer'); localpeerconnection.setremotedescription(new rtcsessiondescription( sdp), function() { trace('make answer') localpeerconnection.createanswer(function( sessiondescription) { // set local description trace('set local session desc answer'); localpeerconnection.setlocaldescription( sessiondescription); // send local sdp remote signallingserver.sendsdp(sessiondescription); }); }); } } // when received ice candidate signallingserver.onreceiveicecandidate = function(candidate) { trace('set remote ice candidate'); localpeerconnection.addicecandidate(new rtcicecandidate(candidate)); } // when room full, alert user signallingserver.onroomfull = function(room) { window.alert('room "' + room + '"" full! please join or create room'); } // ice candidates , send them on // wont called unless sdp has been exchanged localpeerconnection.onicecandidate = function(event) { if (event.candidate) { //!!! send ice candidate on via signalling channel trace("sending candidate"); signallingserver.sendicecandidate(event.candidate); } } // when stream added connection, put in video src localpeerconnection.onaddstream = function(data) { remotevideo.src = window.url.createobjecturl(data.stream); } } function errorhandler(error) { console.error('something went wrong!'); console.error(error); } function trace(text) { console.info(text); }
here signalling server:
function trace(text){ console.info(text); } // connects signalling server given room , ip // has methods exchange sdp , ice candidates var signallingserver = function(room, socketserver){ this.room = room; this.socket = io.connect(socketserver); this.socket.on('full', function (room){ trace('room ' + room + ' full'); this.onroomfull(room); }.bind(this)); this.socket.on('empty', function (room){ this.isinitiator = true; trace('room ' + room + ' empty'); }); this.socket.on('join', function (room){ trace('making request join room ' + room); }); this.socket.on('joined', function (room, numclients){ trace('new user has joined ' + room); trace('room has ' + numclients + ' clients'); //ask host initiate sdp transfer this.onguestjoined(); }.bind(this)); this.socket.on('sdp received', function(sdp){ trace('received sdp '); trace(sdp); this.onreceivesdp(sdp); }.bind(this)); this.socket.on('ice candidate received', function(candidate){ trace('received ice candidate '); trace(candidate); this.onreceiveicecandidate(candidate); }.bind(this)); this.socket.on('log', function (array){ console.log.apply(console, array); }); } signallingserver.prototype = { connect: function(){ if (this.room !== '') { trace('joining room ' + this.room); this.socket.emit('create or join', this.room); } }, close: function(){ trace('disconnecting') this.socket.disconnect(); }, sendsdp: function(sdp){ trace('sending sdp') this.socket.emit('sdp', { room: this.room, sdp: sdp }); }, sendicecandidate: function(candidate){ trace('sending ice candidate'); this.socket.emit('ice candidate', { room: this.room, candidate: candidate }); }, onreceivesdp: function(sdp){ trace('placeholder function: received sdp') }, onguestjoined: function(){ trace('placeholder function: guest joined room') }, onreceiveicecandidate: function(candidate){ trace('placeholder function: received ice candidate') }, onroomfull: function(room){ trace('placeholder function: room full!'); } } window.signallingserver = signallingserver;
and html (can explain livereload.js is?):
<!doctype html> <!--[if lt ie 7]> <html class="no-js lt-ie9 lt-ie8 lt-ie7" lang=""> <![endif]--> <!--[if ie 7]> <html class="no-js lt-ie9 lt-ie8" lang=""> <![endif]--> <!--[if ie 8]> <html class="no-js lt-ie9" lang=""> <![endif]--> <!--[if gt ie 8]> <!--> <html class="no-js" lang=""> <!--<![endif]--> <head> <meta charset="utf-8"> <meta http-equiv="x-ua-compatible" content="ie=edge,chrome=1"> <title></title> <meta name="description" content=""> <meta name="viewport" content="width=device-width, initial-scale=1"> <link rel="stylesheet" href="css/bootstrap.min.css"> <style> body { padding-top: 50px; padding-bottom: 20px; } </style> <link rel="stylesheet" href="css/bootstrap-theme.min.css"> <link rel="stylesheet" href="css/main.css"> <script src="js/vendor/modernizr-2.8.3-respond-1.4.2.min.js"></script> </head> <body> <!--[if lt ie 8]> <p class="browserupgrade"> using <strong>outdated</strong> browser. please <a href="https://browsehappy.com/">upgrade browser</a> improve experience. </p> <![endif]--> <nav class="navbar navbar-default navbar-fixed-top" role="navigation"> <div class="container"> <div class="navbar-header"> <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar" aria-expanded="false"> <span class="sr-only">toggle navigation</span> <span class="icon-bar"></span> <span class="icon-bar"></span> <span class="icon-bar"></span> </button> <a class="navbar-brand" href="#">webrtc video chat</a> </div> <div id="navbar" class="navbar-collapse collapse"> <!-- chatroom name form --> <form class="navbar-form navbar-right form-inline"> <div class="form-group"> <input class="form-control" type="text" id="room-name" placeholder="room name"/> </div> <button class="btn btn-primary" id="btn-video-start">start</button> <button class="btn btn-default" id="btn-video-join">join</button> <button class="btn btn-default" disabled id="btn-video-stop">stop</button> </form> </div> <!--/.navbar-collapse --> </div> </nav> <div class="container main"> <div class="row videos"> <div class="remote-video"> <video width="280" height="250" autoplay id="remote-video"></video> </div> <div class="local-video"> <video width="280" height="250" autoplay id="local-video" muted></video> </div> </div> </div> </div> <!-- /container --> <script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js"></script> <script>window.jquery || document.write('<script src="js/vendor/jquery-1.11.2.min.js"><\/script>')</script> <script src="js/vendor/bootstrap.min.js"></script> <script src="js/vendor/socket.io.js"></script> <script src="js/main.js"></script> <script src="js/signalling.js"></script> <script src="//localhost:9010/livereload.js"></script> </body> </html>
Comments
Post a Comment