diff --git a/html5/verto/js/src/jquery.FSRTC.js b/html5/verto/js/src/jquery.FSRTC.js index d4f25f4fb9..4635106069 100644 --- a/html5/verto/js/src/jquery.FSRTC.js +++ b/html5/verto/js/src/jquery.FSRTC.js @@ -64,8 +64,9 @@ var newLine = []; var index = 0; for (var i = 0; i < elements.length; i++) { - if (index === 3) // Format of media starts from the fourth. - newLine[index++] = payload; // Put target payload to the first. + if (index === 3) { // Format of media starts from the fourth. + newLine[index++] = payload; // Put target payload to the first. + } if (elements[i] !== payload) newLine[index++] = elements[i]; } return newLine.join(' '); @@ -76,7 +77,7 @@ useVideo: null, useStereo: false, userData: null, - iceServers: false, + iceServers: false, videoParams: {}, audioParams: {}, callbacks: { @@ -84,8 +85,7 @@ onICE: function() {}, onOfferSDP: function() {} } - }, - options); + }, options); this.mediaData = { SDP: null, @@ -163,9 +163,9 @@ function setCompat() { $.FSRTC.moz = !!navigator.mozGetUserMedia; //navigator.getUserMedia || (navigator.getUserMedia = navigator.mozGetUserMedia || navigator.webkitGetUserMedia || navigator.msGetUserMedia); - if (!navigator.getUserMedia) { - navigator.getUserMedia = navigator.mozGetUserMedia || navigator.webkitGetUserMedia || navigator.msGetUserMedia; - } + if (!navigator.getUserMedia) { + navigator.getUserMedia = navigator.mozGetUserMedia || navigator.webkitGetUserMedia || navigator.msGetUserMedia; + } } function checkCompat() { @@ -307,7 +307,7 @@ return onChannelError(self, e); }, constraints: self.constraints, - iceServers: self.options.iceServers, + iceServers: self.options.iceServers, offerSDP: { type: "offer", sdp: self.remoteSDP @@ -324,9 +324,9 @@ getUserMedia({ constraints: { audio: { - mandatory: this.options.audioParams, - optional: [] - }, + mandatory: this.options.audioParams, + optional: [] + }, video: this.options.useVideo ? { mandatory: this.options.videoParams, optional: [] @@ -371,7 +371,7 @@ return onChannelError(self, e); }, constraints: self.constraints, - iceServers: self.options.iceServers, + iceServers: self.options.iceServers, }); onStreamSuccess(self); @@ -384,9 +384,9 @@ getUserMedia({ constraints: { audio: { - mandatory: this.options.audioParams, - optional: [] - }, + mandatory: this.options.audioParams, + optional: [] + }, video: this.options.useVideo ? { mandatory: this.options.videoParams, optional: [] @@ -398,11 +398,11 @@ }); /* - navigator.getUserMedia({ + navigator.getUserMedia({ video: this.options.useVideo, audio: true - }, onSuccess, onError); -*/ + }, onSuccess, onError); + */ }; @@ -428,34 +428,34 @@ credential: 'homeo' }; - var iceServers = null; + var iceServers = null; - if (options.iceServers) { - var tmp = options.iceServers;; + if (options.iceServers) { + var tmp = options.iceServers;; - if (typeof(tmp) === "boolean") { - tmp = null; - } + if (typeof(tmp) === "boolean") { + tmp = null; + } - if (tmp && typeof(tmp) !== "array") { - console.warn("iceServers must be an array, reverting to default ice servers"); - tmp = null; - } + if (tmp && typeof(tmp) !== "array") { + console.warn("iceServers must be an array, reverting to default ice servers"); + tmp = null; + } iceServers = { - iceServers: tmp || [STUN] + iceServers: tmp || [STUN] }; if (!moz && !tmp) { - if (parseInt(navigator.userAgent.match(/Chrom(e|ium)\/([0-9]+)\./)[2]) >= 28) TURN = { + if (parseInt(navigator.userAgent.match(/Chrom(e|ium)\/([0-9]+)\./)[2]) >= 28) TURN = { url: 'turn:turn.bistri.com:80', credential: 'homeo', username: 'homeo' - }; + }; - iceServers.iceServers = [STUN]; + iceServers.iceServers = [STUN]; } - } + } var optional = { optional: [] @@ -488,30 +488,30 @@ options.onICESDP(peer.localDescription); //x = 1; /* - x = 1; - peer.createOffer(function(sessionDescription) { - sessionDescription.sdp = serializeSdp(sessionDescription.sdp); - peer.setLocalDescription(sessionDescription); - if (options.onICESDP) { - options.onICESDP(sessionDescription); - } - }, onSdpError, constraints); - */ + x = 1; + peer.createOffer(function(sessionDescription) { + sessionDescription.sdp = serializeSdp(sessionDescription.sdp); + peer.setLocalDescription(sessionDescription); + if (options.onICESDP) { + options.onICESDP(sessionDescription); + } + }, onSdpError, constraints); + */ } } else { if (!x && options.onICESDP) { options.onICESDP(peer.localDescription); //x = 1; /* - x = 1; - peer.createAnswer(function(sessionDescription) { - sessionDescription.sdp = serializeSdp(sessionDescription.sdp); - peer.setLocalDescription(sessionDescription); - if (options.onICESDP) { - options.onICESDP(sessionDescription); - } - }, onSdpError, constraints); - */ + x = 1; + peer.createAnswer(function(sessionDescription) { + sessionDescription.sdp = serializeSdp(sessionDescription.sdp); + peer.setLocalDescription(sessionDescription); + if (options.onICESDP) { + options.onICESDP(sessionDescription); + } + }, onSdpError, constraints); + */ } } } @@ -730,8 +730,8 @@ channel: channel, sendData: function(message) { if (channel) { - channel.send(message); - } + channel.send(message); + } }, stop: function() { @@ -770,8 +770,8 @@ //video.play(); } if (options.onsuccess) { - options.onsuccess(stream); - } + options.onsuccess(stream); + } media = stream; } diff --git a/html5/verto/js/src/jquery.jsonrpcclient.js b/html5/verto/js/src/jquery.jsonrpcclient.js index be2a7a2620..51244e1672 100644 --- a/html5/verto/js/src/jquery.jsonrpcclient.js +++ b/html5/verto/js/src/jquery.jsonrpcclient.js @@ -62,605 +62,599 @@ * The returned instance must have readyState <= 1, and if less than 1, * react to onopen binding. */ - $.JsonRpcClient = function(options) { - var self = this; - this.options = $.extend({ - ajaxUrl : null, - socketUrl : null, ///< The ws-url for default getSocket. - onmessage : null, ///< Other onmessage-handler. - login : null, /// auth login - passwd : null, /// auth passwd - sessid : null, - getSocket : function(onmessage_cb) { return self._getSocket(onmessage_cb); } - }, options); - - self.ws_cnt = 0; + $.JsonRpcClient = function(options) { + var self = this; + this.options = $.extend({ + ajaxUrl : null, + socketUrl : null, ///< The ws-url for default getSocket. + onmessage : null, ///< Other onmessage-handler. + login : null, /// auth login + passwd : null, /// auth passwd + sessid : null, + getSocket : function(onmessage_cb) { return self._getSocket(onmessage_cb); } + }, options); - // Declare an instance version of the onmessage callback to wrap 'this'. - this.wsOnMessage = function(event) { self._wsOnMessage(event); }; - }; + self.ws_cnt = 0; - /// Holding the WebSocket on default getsocket. - $.JsonRpcClient.prototype._ws_socket = null; - - /// Object : { success_cb: cb, error_cb: cb } - $.JsonRpcClient.prototype._ws_callbacks = {}; - - /// The next JSON-RPC request id. - $.JsonRpcClient.prototype._current_id = 1; - - /** - * @fn call - * @memberof $.JsonRpcClient - * - * @param method The method to run on JSON-RPC server. - * @param params The params; an array or object. - * @param success_cb A callback for successful request. - * @param error_cb A callback for error. - */ - $.JsonRpcClient.prototype.call = function(method, params, success_cb, error_cb) { - // Construct the JSON-RPC 2.0 request. - - if (!params) { - params = {}; - } - - if (this.options.sessid) { - params.sessid = this.options.sessid; - } - - var request = { - jsonrpc : '2.0', - method : method, - params : params, - id : this._current_id++ // Increase the id counter to match request/response + // Declare an instance version of the onmessage callback to wrap 'this'. + this.wsOnMessage = function(event) { self._wsOnMessage(event); }; }; - if (!success_cb) { - success_cb = function(e){console.log("Success: ", e);}; - } + /// Holding the WebSocket on default getsocket. + $.JsonRpcClient.prototype._ws_socket = null; - if (!error_cb) { - error_cb = function(e){console.log("Error: ", e);}; - } + /// Object : { success_cb: cb, error_cb: cb } + $.JsonRpcClient.prototype._ws_callbacks = {}; - // Try making a WebSocket call. - var socket = this.options.getSocket(this.wsOnMessage); - if (socket !== null) { - this._wsCall(socket, request, success_cb, error_cb); - return; - } + /// The next JSON-RPC request id. + $.JsonRpcClient.prototype._current_id = 1; - // No WebSocket, and no HTTP backend? This won't work. - if (this.options.ajaxUrl === null) { - throw "$.JsonRpcClient.call used with no websocket and no http endpoint."; - } - - $.ajax({ - type : 'POST', - url : this.options.ajaxUrl, - data : $.toJSON(request), - dataType : 'json', - cache : false, - - success : function(data) { - if ('error' in data) error_cb(data.error, this); - success_cb(data.result, this); - }, - - // JSON-RPC Server could return non-200 on error - error : function(jqXHR, textStatus, errorThrown) { - try { - var response = $.parseJSON(jqXHR.responseText); - if ('console' in window) console.log(response); - error_cb(response.error, this); - } - catch (err) { - // Perhaps the responseText wasn't really a jsonrpc-error. - error_cb({ error: jqXHR.responseText }, this); - } - } - }); - }; - - /** - * Notify sends a command to the server that won't need a response. In http, there is probably - * an empty response - that will be dropped, but in ws there should be no response at all. - * - * This is very similar to call, but has no id and no handling of callbacks. - * - * @fn notify - * @memberof $.JsonRpcClient - * - * @param method The method to run on JSON-RPC server. - * @param params The params; an array or object. - */ - $.JsonRpcClient.prototype.notify = function(method, params) { + /** + * @fn call + * @memberof $.JsonRpcClient + * + * @param method The method to run on JSON-RPC server. + * @param params The params; an array or object. + * @param success_cb A callback for successful request. + * @param error_cb A callback for error. + */ + $.JsonRpcClient.prototype.call = function(method, params, success_cb, error_cb) { // Construct the JSON-RPC 2.0 request. - if (this.options.sessid) { - params.sessid = this.options.sessid; - } - - var request = { - jsonrpc: '2.0', - method: method, - params: params - }; - - // Try making a WebSocket call. - var socket = this.options.getSocket(this.wsOnMessage); - if (socket !== null) { - this._wsCall(socket, request); - return; - } - - // No WebSocket, and no HTTP backend? This won't work. - if (this.options.ajaxUrl === null) { - throw "$.JsonRpcClient.notify used with no websocket and no http endpoint."; - } - - $.ajax({ - type : 'POST', - url : this.options.ajaxUrl, - data : $.toJSON(request), - dataType : 'json', - cache : false - }); - }; - - /** - * Make a batch-call by using a callback. - * - * The callback will get an object "batch" as only argument. On batch, you can call the methods - * "call" and "notify" just as if it was a normal $.JsonRpcClient object, and all calls will be - * sent as a batch call then the callback is done. - * - * @fn batch - * @memberof $.JsonRpcClient - * - * @param callback The main function which will get a batch handler to run call and notify on. - * @param all_done_cb A callback function to call after all results have been handled. - * @param error_cb A callback function to call if there is an error from the server. - * Note, that batch calls should always get an overall success, and the - * only error - */ - $.JsonRpcClient.prototype.batch = function(callback, all_done_cb, error_cb) { - var batch = new $.JsonRpcClient._batchObject(this, all_done_cb, error_cb); - callback(batch); - batch._execute(); - }; - - /** - * The default getSocket handler. - * - * @param onmessage_cb The callback to be bound to onmessage events on the socket. - * - * @fn _getSocket - * @memberof $.JsonRpcClient - */ - - $.JsonRpcClient.prototype.socketReady = function() { - if (this._ws_socket === null || this._ws_socket.readyState > 1) { - return false; - } - - return true; - } - - $.JsonRpcClient.prototype.closeSocket = function() { - if (self.socketReady()) { - this._ws_socket.onclose = function (w) {console.log("Closing Socket")} - this._ws_socket.close(); - } - } - - $.JsonRpcClient.prototype.loginData = function(params) { - self.options.login = params.login; - self.options.passwd = params.passwd; - } - - $.JsonRpcClient.prototype.connectSocket = function(onmessage_cb) { - var self = this; - - if (self.to) { - clearTimeout(self.to); - } - - if (!self.socketReady()) { - self.authing = false; - - if (self._ws_socket) { - delete self._ws_socket; - } - - // No socket, or dying socket, let's get a new one. - self._ws_socket = new WebSocket(self.options.socketUrl); - - if (self._ws_socket) { - // Set up onmessage handler. - self._ws_socket.onmessage = onmessage_cb; - self._ws_socket.onclose = function (w) { - if (!self.ws_sleep) { - self.ws_sleep = 1000; - } - - if (self.options.onWSClose) { - self.options.onWSClose(self); - } - - console.error("Websocket Lost " + self.ws_cnt + " sleep: " + self.ws_sleep + "msec"); - - self.to = setTimeout(function() { - console.log("Attempting Reconnection...."); - self.connectSocket(onmessage_cb); - }, self.ws_sleep); - - self.ws_cnt++; - - if (self.ws_sleep < 3000 && (self.ws_cnt % 10) == 0) { - self.ws_sleep += 1000; - } - } - - // Set up sending of message for when the socket is open. - self._ws_socket.onopen = function() { - if (self.to) { - clearTimeout(self.to); - } - self.ws_sleep = 1000; - self.ws_cnt = 0; - if (self.options.onWSConnect) { - self.options.onWSConnect(self); - } - - var req; - // Send the requests. - while (req = $.JsonRpcClient.q.pop()) { - self._ws_socket.send(req); - } - } - } - } - - return self._ws_socket ? true : false; - } - - $.JsonRpcClient.prototype._getSocket = function(onmessage_cb) { - // If there is no ws url set, we don't have a socket. - // Likewise, if there is no window.WebSocket. - if (this.options.socketUrl === null || !("WebSocket" in window)) return null; - - this.connectSocket(onmessage_cb); - - return this._ws_socket; - }; - - /** - * Queue to save messages delivered when websocket is not ready - */ - $.JsonRpcClient.q = []; - - /** - * Internal handler to dispatch a JRON-RPC request through a websocket. - * - * @fn _wsCall - * @memberof $.JsonRpcClient - */ - $.JsonRpcClient.prototype._wsCall = function(socket, request, success_cb, error_cb) { - var request_json = $.toJSON(request); - - if (socket.readyState < 1) { - // The websocket is not open yet; we have to set sending of the message in onopen. - self = this; // In closure below, this is set to the WebSocket. Use self instead. - - $.JsonRpcClient.q.push(request_json); - - - } - else { - // We have a socket and it should be ready to send on. - socket.send(request_json); - } - - // Setup callbacks. If there is an id, this is a call and not a notify. - if ('id' in request && typeof success_cb !== 'undefined') { - this._ws_callbacks[request.id] = { request: request_json, request_obj: request, success_cb: success_cb, error_cb: error_cb }; - } - }; - - /** - * Internal handler for the websocket messages. It determines if the message is a JSON-RPC - * response, and if so, tries to couple it with a given callback. Otherwise, it falls back to - * given external onmessage-handler, if any. - * - * @param event The websocket onmessage-event. - */ - $.JsonRpcClient.prototype._wsOnMessage = function(event) { - // Check if this could be a JSON RPC message. - var response; - try { - response = $.parseJSON(event.data); - - /// @todo Make using the jsonrcp 2.0 check optional, to use this on JSON-RPC 1 backends. - - if (typeof response === 'object' - && 'jsonrpc' in response - && response.jsonrpc === '2.0') { - - /// @todo Handle bad response (without id). - - // If this is an object with result, it is a response. - if ('result' in response && this._ws_callbacks[response.id]) { - // Get the success callback. - var success_cb = this._ws_callbacks[response.id].success_cb; - -/* - // set the sessid if present - if ('sessid' in response.result && !this.options.sessid || (this.options.sessid != response.result.sessid)) { - this.options.sessid = response.result.sessid; - if (this.options.sessid) { - console.log("setting session UUID to: " + this.options.sessid); - } - } -*/ - // Delete the callback from the storage. - delete this._ws_callbacks[response.id]; - - // Run callback with result as parameter. - success_cb(response.result, this); - return; + if (!params) { + params = {}; } - // If this is an object with error, it is an error response. - else if ('error' in response && this._ws_callbacks[response.id]) { - - // Get the error callback. - var error_cb = this._ws_callbacks[response.id].error_cb; - var orig_req = this._ws_callbacks[response.id].request; - - // if this is an auth request, send the credentials and resend the failed request - if (!self.authing && response.error.code == -32000 && self.options.login && self.options.passwd) { - self.authing = true; - - this.call("login", { login: self.options.login, passwd: self.options.passwd}, - this._ws_callbacks[response.id].request_obj.method == "login" - ? - function(e) { - self.authing = false; - console.log("logged in"); - delete self._ws_callbacks[response.id]; - - if (self.options.onWSLogin) { - self.options.onWSLogin(true, self); - } - } - - : - - function(e) { - self.authing = false; - console.log("logged in, resending request id: " + response.id); - var socket = self.options.getSocket(self.wsOnMessage); - if (socket !== null) { - socket.send(orig_req); - } - if (self.options.onWSLogin) { - self.options.onWSLogin(true, self); - } - }, - - function(e) { - console.log("error logging in, request id:", response.id); - delete self._ws_callbacks[response.id]; - error_cb(response.error, this); - if (self.options.onWSLogin) { - self.options.onWSLogin(false, self); - } - } - - ); - return; - } - - // Delete the callback from the storage. - delete this._ws_callbacks[response.id]; - - // Run callback with the error object as parameter. - error_cb(response.error, this); - - return; + if (this.options.sessid) { + params.sessid = this.options.sessid; } - } - } - catch (err) { - // Probably an error while parsing a non json-string as json. All real JSON-RPC cases are - // handled above, and the fallback method is called below. - console.log("ERROR: "+ err); - return; - } - // This is not a JSON-RPC response. Call the fallback message handler, if given. - if (typeof this.options.onmessage === 'function') { - event.eventData = response; - if (!event.eventData) { - event.eventData = {}; - } - - var reply = this.options.onmessage(event); - - if (reply && typeof reply === "object" && event.eventData.id) { - var msg = { - jsonrpc: "2.0", - id: event.eventData.id, - result: reply - }; - - var socket = self.options.getSocket(self.wsOnMessage); - if (socket !== null) { - socket.send($.toJSON(msg)); - } - } - - } - }; - - - /************************************************************************************************ - * Batch object with methods - ************************************************************************************************/ - - /** - * Handling object for batch calls. - */ - $.JsonRpcClient._batchObject = function(jsonrpcclient, all_done_cb, error_cb) { - // Array of objects to hold the call and notify requests. Each objects will have the request - // object, and unless it is a notify, success_cb and error_cb. - this._requests = []; - - this.jsonrpcclient = jsonrpcclient; - this.all_done_cb = all_done_cb; - this.error_cb = typeof error_cb === 'function' ? error_cb : function() {}; - - }; - - /** - * @sa $.JsonRpcClient.prototype.call - */ - $.JsonRpcClient._batchObject.prototype.call = function(method, params, success_cb, error_cb) { - - if (!params) { - params = {}; - } - - if (this.options.sessid) { - params.sessid = this.options.sessid; - } - - if (!success_cb) { - success_cb = function(e){console.log("Success: ", e);}; - } - - if (!error_cb) { - error_cb = function(e){console.log("Error: ", e);}; - } - - this._requests.push({ - request : { - jsonrpc : '2.0', - method : method, - params : params, - id : this.jsonrpcclient._current_id++ // Use the client's id series. - }, - success_cb : success_cb, - error_cb : error_cb - }); - }; - - /** - * @sa $.JsonRpcClient.prototype.notify - */ - $.JsonRpcClient._batchObject.prototype.notify = function(method, params) { - if (this.options.sessid) { - params.sessid = this.options.sessid; - } - - this._requests.push({ - request : { - jsonrpc : '2.0', - method : method, - params : params - } - }); - }; - - /** - * Executes the batched up calls. - */ - $.JsonRpcClient._batchObject.prototype._execute = function() { - var self = this; - - if (this._requests.length === 0) return; // All done :P - - // Collect all request data and sort handlers by request id. - var batch_request = []; - var handlers = {}; - - // If we have a WebSocket, just send the requests individually like normal calls. - var socket = self.jsonrpcclient.options.getSocket(self.jsonrpcclient.wsOnMessage); - if (socket !== null) { - for (var i = 0; i < this._requests.length; i++) { - var call = this._requests[i]; - var success_cb = ('success_cb' in call) ? call.success_cb : undefined; - var error_cb = ('error_cb' in call) ? call.error_cb : undefined; - self.jsonrpcclient._wsCall(socket, call.request, success_cb, error_cb); - } - if (typeof all_done_cb === 'function') all_done_cb(result); - return; - } - - for (var i = 0; i < this._requests.length; i++) { - var call = this._requests[i]; - batch_request.push(call.request); - - // If the request has an id, it should handle returns (otherwise it's a notify). - if ('id' in call.request) { - handlers[call.request.id] = { - success_cb : call.success_cb, - error_cb : call.error_cb + var request = { + jsonrpc : '2.0', + method : method, + params : params, + id : this._current_id++ // Increase the id counter to match request/response }; - } - } - var success_cb = function(data) { self._batchCb(data, handlers, self.all_done_cb); }; - - // No WebSocket, and no HTTP backend? This won't work. - if (self.jsonrpcclient.options.ajaxUrl === null) { - throw "$.JsonRpcClient.batch used with no websocket and no http endpoint."; - } - - // Send request - $.ajax({ - url : self.jsonrpcclient.options.ajaxUrl, - data : $.toJSON(batch_request), - dataType : 'json', - cache : false, - type : 'POST', - - // Batch-requests should always return 200 - error : function(jqXHR, textStatus, errorThrown) { - self.error_cb(jqXHR, textStatus, errorThrown); - }, - success : success_cb - }); - }; - - /** - * Internal helper to match the result array from a batch call to their respective callbacks. - * - * @fn _batchCb - * @memberof $.JsonRpcClient - */ - $.JsonRpcClient._batchObject.prototype._batchCb = function(result, handlers, all_done_cb) { - for (var i = 0; i < result.length; i++) { - var response = result[i]; - - // Handle error - if ('error' in response) { - if (response.id === null || !(response.id in handlers)) { - // An error on a notify? Just log it to the console. - if ('console' in window) console.log(response); + if (!success_cb) { + success_cb = function(e){console.log("Success: ", e);}; } - else handlers[response.id].error_cb(response.error, this); - } - else { - // Here we should always have a correct id and no error. - if (!(response.id in handlers) && 'console' in window) console.log(response); - else handlers[response.id].success_cb(response.result, this); - } + + if (!error_cb) { + error_cb = function(e){console.log("Error: ", e);}; + } + + // Try making a WebSocket call. + var socket = this.options.getSocket(this.wsOnMessage); + if (socket !== null) { + this._wsCall(socket, request, success_cb, error_cb); + return; + } + + // No WebSocket, and no HTTP backend? This won't work. + if (this.options.ajaxUrl === null) { + throw "$.JsonRpcClient.call used with no websocket and no http endpoint."; + } + + $.ajax({ + type : 'POST', + url : this.options.ajaxUrl, + data : $.toJSON(request), + dataType : 'json', + cache : false, + + success : function(data) { + if ('error' in data) error_cb(data.error, this); + success_cb(data.result, this); + }, + + // JSON-RPC Server could return non-200 on error + error : function(jqXHR, textStatus, errorThrown) { + try { + var response = $.parseJSON(jqXHR.responseText); + + if ('console' in window) console.log(response); + + error_cb(response.error, this); + } catch (err) { + // Perhaps the responseText wasn't really a jsonrpc-error. + error_cb({ error: jqXHR.responseText }, this); + } + } + }); + }; + + /** + * Notify sends a command to the server that won't need a response. In http, there is probably + * an empty response - that will be dropped, but in ws there should be no response at all. + * + * This is very similar to call, but has no id and no handling of callbacks. + * + * @fn notify + * @memberof $.JsonRpcClient + * + * @param method The method to run on JSON-RPC server. + * @param params The params; an array or object. + */ + $.JsonRpcClient.prototype.notify = function(method, params) { + // Construct the JSON-RPC 2.0 request. + + if (this.options.sessid) { + params.sessid = this.options.sessid; + } + + var request = { + jsonrpc: '2.0', + method: method, + params: params + }; + + // Try making a WebSocket call. + var socket = this.options.getSocket(this.wsOnMessage); + if (socket !== null) { + this._wsCall(socket, request); + return; + } + + // No WebSocket, and no HTTP backend? This won't work. + if (this.options.ajaxUrl === null) { + throw "$.JsonRpcClient.notify used with no websocket and no http endpoint."; + } + + $.ajax({ + type : 'POST', + url : this.options.ajaxUrl, + data : $.toJSON(request), + dataType : 'json', + cache : false + }); + }; + + /** + * Make a batch-call by using a callback. + * + * The callback will get an object "batch" as only argument. On batch, you can call the methods + * "call" and "notify" just as if it was a normal $.JsonRpcClient object, and all calls will be + * sent as a batch call then the callback is done. + * + * @fn batch + * @memberof $.JsonRpcClient + * + * @param callback The main function which will get a batch handler to run call and notify on. + * @param all_done_cb A callback function to call after all results have been handled. + * @param error_cb A callback function to call if there is an error from the server. + * Note, that batch calls should always get an overall success, and the + * only error + */ + $.JsonRpcClient.prototype.batch = function(callback, all_done_cb, error_cb) { + var batch = new $.JsonRpcClient._batchObject(this, all_done_cb, error_cb); + callback(batch); + batch._execute(); + }; + + /** + * The default getSocket handler. + * + * @param onmessage_cb The callback to be bound to onmessage events on the socket. + * + * @fn _getSocket + * @memberof $.JsonRpcClient + */ + + $.JsonRpcClient.prototype.socketReady = function() { + if (this._ws_socket === null || this._ws_socket.readyState > 1) { + return false; + } + + return true; } - if (typeof all_done_cb === 'function') all_done_cb(result); - }; + $.JsonRpcClient.prototype.closeSocket = function() { + if (self.socketReady()) { + this._ws_socket.onclose = function (w) {console.log("Closing Socket")} + this._ws_socket.close(); + } + } + + $.JsonRpcClient.prototype.loginData = function(params) { + self.options.login = params.login; + self.options.passwd = params.passwd; + } + + $.JsonRpcClient.prototype.connectSocket = function(onmessage_cb) { + var self = this; + + if (self.to) { + clearTimeout(self.to); + } + + if (!self.socketReady()) { + self.authing = false; + + if (self._ws_socket) { + delete self._ws_socket; + } + + // No socket, or dying socket, let's get a new one. + self._ws_socket = new WebSocket(self.options.socketUrl); + + if (self._ws_socket) { + // Set up onmessage handler. + self._ws_socket.onmessage = onmessage_cb; + self._ws_socket.onclose = function (w) { + if (!self.ws_sleep) { + self.ws_sleep = 1000; + } + + if (self.options.onWSClose) { + self.options.onWSClose(self); + } + + console.error("Websocket Lost " + self.ws_cnt + " sleep: " + self.ws_sleep + "msec"); + + self.to = setTimeout(function() { + console.log("Attempting Reconnection...."); + self.connectSocket(onmessage_cb); + }, self.ws_sleep); + + self.ws_cnt++; + + if (self.ws_sleep < 3000 && (self.ws_cnt % 10) == 0) { + self.ws_sleep += 1000; + } + } + + // Set up sending of message for when the socket is open. + self._ws_socket.onopen = function() { + if (self.to) { + clearTimeout(self.to); + } + self.ws_sleep = 1000; + self.ws_cnt = 0; + if (self.options.onWSConnect) { + self.options.onWSConnect(self); + } + + var req; + // Send the requests. + while (req = $.JsonRpcClient.q.pop()) { + self._ws_socket.send(req); + } + } + } + } + + return self._ws_socket ? true : false; + } + + $.JsonRpcClient.prototype._getSocket = function(onmessage_cb) { + // If there is no ws url set, we don't have a socket. + // Likewise, if there is no window.WebSocket. + if (this.options.socketUrl === null || !("WebSocket" in window)) return null; + + this.connectSocket(onmessage_cb); + + return this._ws_socket; + }; + + /** + * Queue to save messages delivered when websocket is not ready + */ + $.JsonRpcClient.q = []; + + /** + * Internal handler to dispatch a JRON-RPC request through a websocket. + * + * @fn _wsCall + * @memberof $.JsonRpcClient + */ + $.JsonRpcClient.prototype._wsCall = function(socket, request, success_cb, error_cb) { + var request_json = $.toJSON(request); + + if (socket.readyState < 1) { + // The websocket is not open yet; we have to set sending of the message in onopen. + self = this; // In closure below, this is set to the WebSocket. Use self instead. + $.JsonRpcClient.q.push(request_json); + } else { + // We have a socket and it should be ready to send on. + socket.send(request_json); + } + + // Setup callbacks. If there is an id, this is a call and not a notify. + if ('id' in request && typeof success_cb !== 'undefined') { + this._ws_callbacks[request.id] = { request: request_json, request_obj: request, success_cb: success_cb, error_cb: error_cb }; + } + }; + + /** + * Internal handler for the websocket messages. It determines if the message is a JSON-RPC + * response, and if so, tries to couple it with a given callback. Otherwise, it falls back to + * given external onmessage-handler, if any. + * + * @param event The websocket onmessage-event. + */ + $.JsonRpcClient.prototype._wsOnMessage = function(event) { + // Check if this could be a JSON RPC message. + var response; + try { + response = $.parseJSON(event.data); + + /// @todo Make using the jsonrcp 2.0 check optional, to use this on JSON-RPC 1 backends. + + if (typeof response === 'object' + && 'jsonrpc' in response + && response.jsonrpc === '2.0') { + + /// @todo Handle bad response (without id). + + // If this is an object with result, it is a response. + if ('result' in response && this._ws_callbacks[response.id]) { + // Get the success callback. + var success_cb = this._ws_callbacks[response.id].success_cb; + + /* + // set the sessid if present + if ('sessid' in response.result && !this.options.sessid || (this.options.sessid != response.result.sessid)) { + this.options.sessid = response.result.sessid; + if (this.options.sessid) { + console.log("setting session UUID to: " + this.options.sessid); + } + } + */ + // Delete the callback from the storage. + delete this._ws_callbacks[response.id]; + + // Run callback with result as parameter. + success_cb(response.result, this); + return; + } else if ('error' in response && this._ws_callbacks[response.id]) { + // If this is an object with error, it is an error response. + + // Get the error callback. + var error_cb = this._ws_callbacks[response.id].error_cb; + var orig_req = this._ws_callbacks[response.id].request; + + // if this is an auth request, send the credentials and resend the failed request + if (!self.authing && response.error.code == -32000 && self.options.login && self.options.passwd) { + self.authing = true; + + this.call("login", { login: self.options.login, passwd: self.options.passwd}, + this._ws_callbacks[response.id].request_obj.method == "login" + ? + function(e) { + self.authing = false; + console.log("logged in"); + delete self._ws_callbacks[response.id]; + + if (self.options.onWSLogin) { + self.options.onWSLogin(true, self); + } + } + + : + + function(e) { + self.authing = false; + console.log("logged in, resending request id: " + response.id); + var socket = self.options.getSocket(self.wsOnMessage); + if (socket !== null) { + socket.send(orig_req); + } + if (self.options.onWSLogin) { + self.options.onWSLogin(true, self); + } + }, + + function(e) { + console.log("error logging in, request id:", response.id); + delete self._ws_callbacks[response.id]; + error_cb(response.error, this); + if (self.options.onWSLogin) { + self.options.onWSLogin(false, self); + } + }); + return; + } + + // Delete the callback from the storage. + delete this._ws_callbacks[response.id]; + + // Run callback with the error object as parameter. + error_cb(response.error, this); + return; + } + } + } catch (err) { + // Probably an error while parsing a non json-string as json. All real JSON-RPC cases are + // handled above, and the fallback method is called below. + console.log("ERROR: "+ err); + return; + } + + // This is not a JSON-RPC response. Call the fallback message handler, if given. + if (typeof this.options.onmessage === 'function') { + event.eventData = response; + if (!event.eventData) { + event.eventData = {}; + } + + var reply = this.options.onmessage(event); + + if (reply && typeof reply === "object" && event.eventData.id) { + var msg = { + jsonrpc: "2.0", + id: event.eventData.id, + result: reply + }; + + var socket = self.options.getSocket(self.wsOnMessage); + if (socket !== null) { + socket.send($.toJSON(msg)); + } + } + } + }; + + + /************************************************************************************************ + * Batch object with methods + ************************************************************************************************/ + + /** + * Handling object for batch calls. + */ + $.JsonRpcClient._batchObject = function(jsonrpcclient, all_done_cb, error_cb) { + // Array of objects to hold the call and notify requests. Each objects will have the request + // object, and unless it is a notify, success_cb and error_cb. + this._requests = []; + + this.jsonrpcclient = jsonrpcclient; + this.all_done_cb = all_done_cb; + this.error_cb = typeof error_cb === 'function' ? error_cb : function() {}; + + }; + + /** + * @sa $.JsonRpcClient.prototype.call + */ + $.JsonRpcClient._batchObject.prototype.call = function(method, params, success_cb, error_cb) { + + if (!params) { + params = {}; + } + + if (this.options.sessid) { + params.sessid = this.options.sessid; + } + + if (!success_cb) { + success_cb = function(e){console.log("Success: ", e);}; + } + + if (!error_cb) { + error_cb = function(e){console.log("Error: ", e);}; + } + + this._requests.push({ + request : { + jsonrpc : '2.0', + method : method, + params : params, + id : this.jsonrpcclient._current_id++ // Use the client's id series. + }, + success_cb : success_cb, + error_cb : error_cb + }); + }; + + /** + * @sa $.JsonRpcClient.prototype.notify + */ + $.JsonRpcClient._batchObject.prototype.notify = function(method, params) { + if (this.options.sessid) { + params.sessid = this.options.sessid; + } + + this._requests.push({ + request : { + jsonrpc : '2.0', + method : method, + params : params + } + }); + }; + + /** + * Executes the batched up calls. + */ + $.JsonRpcClient._batchObject.prototype._execute = function() { + var self = this; + + if (this._requests.length === 0) return; // All done :P + + // Collect all request data and sort handlers by request id. + var batch_request = []; + var handlers = {}; + + // If we have a WebSocket, just send the requests individually like normal calls. + var socket = self.jsonrpcclient.options.getSocket(self.jsonrpcclient.wsOnMessage); + if (socket !== null) { + for (var i = 0; i < this._requests.length; i++) { + var call = this._requests[i]; + var success_cb = ('success_cb' in call) ? call.success_cb : undefined; + var error_cb = ('error_cb' in call) ? call.error_cb : undefined; + self.jsonrpcclient._wsCall(socket, call.request, success_cb, error_cb); + } + + if (typeof all_done_cb === 'function') all_done_cb(result); + return; + } + + for (var i = 0; i < this._requests.length; i++) { + var call = this._requests[i]; + batch_request.push(call.request); + + // If the request has an id, it should handle returns (otherwise it's a notify). + if ('id' in call.request) { + handlers[call.request.id] = { + success_cb : call.success_cb, + error_cb : call.error_cb + }; + } + } + + var success_cb = function(data) { self._batchCb(data, handlers, self.all_done_cb); }; + + // No WebSocket, and no HTTP backend? This won't work. + if (self.jsonrpcclient.options.ajaxUrl === null) { + throw "$.JsonRpcClient.batch used with no websocket and no http endpoint."; + } + + // Send request + $.ajax({ + url : self.jsonrpcclient.options.ajaxUrl, + data : $.toJSON(batch_request), + dataType : 'json', + cache : false, + type : 'POST', + + // Batch-requests should always return 200 + error : function(jqXHR, textStatus, errorThrown) { + self.error_cb(jqXHR, textStatus, errorThrown); + }, + success : success_cb + }); + }; + + /** + * Internal helper to match the result array from a batch call to their respective callbacks. + * + * @fn _batchCb + * @memberof $.JsonRpcClient + */ + $.JsonRpcClient._batchObject.prototype._batchCb = function(result, handlers, all_done_cb) { + for (var i = 0; i < result.length; i++) { + var response = result[i]; + + // Handle error + if ('error' in response) { + if (response.id === null || !(response.id in handlers)) { + // An error on a notify? Just log it to the console. + if ('console' in window) console.log(response); + } else { + handlers[response.id].error_cb(response.error, this); + } + } else { + // Here we should always have a correct id and no error. + if (!(response.id in handlers) && 'console' in window) { + console.log(response); + } else { + handlers[response.id].success_cb(response.result, this); + } + } + } + + if (typeof all_done_cb === 'function') all_done_cb(result); + }; })(jQuery); diff --git a/html5/verto/js/src/jquery.verto.js b/html5/verto/js/src/jquery.verto.js index a9f028d6d9..4beedc6548 100644 --- a/html5/verto/js/src/jquery.verto.js +++ b/html5/verto/js/src/jquery.verto.js @@ -73,10 +73,9 @@ tag: null, videoParams: {}, audioParams: {}, - iceServers: false, + iceServers: false, ringSleep: 6000 - }, - options); + }, options); verto.sessid = $.cookie('verto_session_uuid') || generateGUID(); $.cookie('verto_session_uuid', verto.sessid, { @@ -84,9 +83,7 @@ }); verto.dialogs = {}; - verto.callbacks = callbacks || {}; - verto.eventSUBS = {}; verto.rpcClient = new $.JsonRpcClient({ @@ -123,7 +120,6 @@ $.verto.prototype.iceServers = function(on) { var verto = this; - verto.options.iceServers = on; }; @@ -172,7 +168,7 @@ $.verto.prototype.processReply = function(method, success, e) { var verto = this; - var i; + var i; //console.log("Response: " + method, success, e); @@ -228,7 +224,7 @@ } var SERNO = 1; - + function do_subscribe(verto, channel, subChannels, sparams) { var params = sparams || {}; @@ -298,7 +294,7 @@ $.verto.prototype.unsubscribe = function(handle) { var verto = this; - var i; + var i; if (!handle) { for (i in verto.eventSUBS) { @@ -309,7 +305,7 @@ } else { var unsubChannels = {}; var sendChannels = []; - var channel; + var channel; if (typeof(handle) == "string") { delete verto.eventSUBS[handle]; @@ -368,13 +364,13 @@ $.verto.prototype.purge = function(callID) { var verto = this; var x = 0; - var i; + var i; for (i in verto.dialogs) { if (!x) { console.log("purging dialogs"); } - x++; + x++; verto.dialogs[i].setState($.verto.enum.state.purge); } @@ -423,10 +419,10 @@ $.verto.prototype.handleMessage = function(data) { var verto = this; - if (!(data && data.method)) { - console.error("Invalid Data", data); - return; - } + if (!(data && data.method)) { + console.error("Invalid Data", data); + return; + } if (data.params.callID) { var dialog = verto.dialogs[data.params.callID]; @@ -467,10 +463,10 @@ data.params.useStereo = true; } - dialog = new $.verto.dialog($.verto.enum.direction.inbound, verto, data.params); + dialog = new $.verto.dialog($.verto.enum.direction.inbound, verto, data.params); dialog.setState($.verto.enum.state.recovering); - break; + break; case 'verto.invite': if (data.params.sdp && data.params.sdp.indexOf("m=video") > 0) { @@ -510,10 +506,10 @@ } } - if (!list && key && key === verto.sessid) { - if (verto.callbacks.onMessage) { - verto.callbacks.onMessage(verto, null, $.verto.enum.message.pvtEvent, data.params); - } + if (!list && key && key === verto.sessid) { + if (verto.callbacks.onMessage) { + verto.callbacks.onMessage(verto, null, $.verto.enum.message.pvtEvent, data.params); + } } else if (!list && key && verto.dialogs[key]) { verto.dialogs[key].sendMessage($.verto.enum.message.pvtEvent, data.params); } else if (!list) { @@ -944,21 +940,21 @@ la.verto.unsubscribe(binding); }; - la.sendCommand = function(cmd, obj) { + la.sendCommand = function(cmd, obj) { var self = la; - self.broadcast(self.context, { - liveArray: { + self.broadcast(self.context, { + liveArray: { command: cmd, context: self.context, name: self.name, obj: obj } - }); - }; + }); + }; la.bootstrap = function(obj) { var self = la; - la.sendCommand("bootstrap", obj); + la.sendCommand("bootstrap", obj); //self.heartbeat(); }; @@ -1128,7 +1124,7 @@ } else { obj.errs = 0; } - + }; la.onChange(la, { @@ -1138,211 +1134,205 @@ }; var CONFMAN_SERNO = 1; - + $.verto.confMan = function(verto, params) { - var confMan = this; - conf + var confMan = this; + conf confMan.params = $.extend({ - tableID: null, - statusID: null, - mainModID: null, - dialog: null, - hasVid: false, - laData: null, - onBroadcast: null, - onLaChange: null, - onLaRow: null - }, - params); + tableID: null, + statusID: null, + mainModID: null, + dialog: null, + hasVid: false, + laData: null, + onBroadcast: null, + onLaChange: null, + onLaRow: null + }, params); - confMan.verto = verto; - confMan.serno = CONFMAN_SERNO++; + confMan.verto = verto; + confMan.serno = CONFMAN_SERNO++; - function genMainMod(jq) { - var play_id = "play_" + confMan.serno; - var stop_id = "stop_" + confMan.serno; - var recording_id = "recording_" + confMan.serno; - var rec_stop_id = "recording_stop" + confMan.serno; - var div_id = "confman_" + confMan.serno; + function genMainMod(jq) { + var play_id = "play_" + confMan.serno; + var stop_id = "stop_" + confMan.serno; + var recording_id = "recording_" + confMan.serno; + var rec_stop_id = "recording_stop" + confMan.serno; + var div_id = "confman_" + confMan.serno; - var html = "

" + - "" + - "" + - "" + - "" + var html = "

" + + "" + + "" + + "" + + "" - + "

"; + + "

"; - jq.html(html); + jq.html(html); - $("#" + play_id).click(function() { - var file = prompt("Please enter file name", ""); - confMan.modCommand("play", null, file); - }); + $("#" + play_id).click(function() { + var file = prompt("Please enter file name", ""); + confMan.modCommand("play", null, file); + }); - $("#" + stop_id).click(function() { - confMan.modCommand("stop", null, "all"); - }); + $("#" + stop_id).click(function() { + confMan.modCommand("stop", null, "all"); + }); - $("#" + recording_id).click(function() { - var file = prompt("Please enter file name", ""); - confMan.modCommand("recording", null, ["start", file]); - }); + $("#" + recording_id).click(function() { + var file = prompt("Please enter file name", ""); + confMan.modCommand("recording", null, ["start", file]); + }); - $("#" + rec_stop_id).click(function() { - confMan.modCommand("recording", null, ["stop", "all"]); - }); + $("#" + rec_stop_id).click(function() { + confMan.modCommand("recording", null, ["stop", "all"]); + }); - } + } - function genControls(jq, rowid) { - var x = parseInt(rowid); - var kick_id = "kick_" + x; - var tmute_id = "tmute_" + x; - var box_id = "box_" + x; - var volup_id = "volume_in_up" + x; - var voldn_id = "volume_in_dn" + x; - var transfer_id = "transfer" + x; - - - var html = "
" + - "" + - "" + - "" + - "" + - "" + - "
" - ; - - jq.html(html); - - if (!jq.data("mouse")) { - $("#" + box_id).hide(); - } - - jq.mouseover(function(e) { - jq.data({"mouse": true}); - $("#" + box_id).show(); - }); - - jq.mouseout(function(e) { - jq.data({"mouse": false}); - $("#" + box_id).hide(); - }); - - $("#" + transfer_id).click(function() { - var xten = prompt("Enter Extension"); - confMan.modCommand("transfer", x, xten); - }); - - $("#" + kick_id).click(function() { - confMan.modCommand("kick", x); - }); - - $("#" + tmute_id).click(function() { - confMan.modCommand("tmute", x); - }); - - $("#" + volup_id).click(function() { - confMan.modCommand("volume_in", x, "up"); - }); - - $("#" + voldn_id).click(function() { - confMan.modCommand("volume_in", x, "down"); - }); - - return html; - } + function genControls(jq, rowid) { + var x = parseInt(rowid); + var kick_id = "kick_" + x; + var tmute_id = "tmute_" + x; + var box_id = "box_" + x; + var volup_id = "volume_in_up" + x; + var voldn_id = "volume_in_dn" + x; + var transfer_id = "transfer" + x; + var html = "
" + + "" + + "" + + "" + + "" + + "" + + "
" + ; + + jq.html(html); + + if (!jq.data("mouse")) { + $("#" + box_id).hide(); + } + + jq.mouseover(function(e) { + jq.data({"mouse": true}); + $("#" + box_id).show(); + }); + + jq.mouseout(function(e) { + jq.data({"mouse": false}); + $("#" + box_id).hide(); + }); + + $("#" + transfer_id).click(function() { + var xten = prompt("Enter Extension"); + confMan.modCommand("transfer", x, xten); + }); + + $("#" + kick_id).click(function() { + confMan.modCommand("kick", x); + }); + + $("#" + tmute_id).click(function() { + confMan.modCommand("tmute", x); + }); + + $("#" + volup_id).click(function() { + confMan.modCommand("volume_in", x, "up"); + }); + + $("#" + voldn_id).click(function() { + confMan.modCommand("volume_in", x, "down"); + }); + + return html; + } + + var atitle = ""; + var awidth = 0; - var atitle = ""; - var awidth = 0; - //$(".jsDataTable").width(confMan.params.hasVid ? "900px" : "800px"); - - if (confMan.params.laData.role === "moderator") { - atitle = "Action"; - awidth = 200; - - if (confMan.params.mainModID) { - genMainMod($(confMan.params.mainModID)); - $(confMan.params.displayID).html("Moderator Controls Ready

") - } else { - $(confMan.params.mainModID).html(""); - } - verto.subscribe(confMan.params.laData.modChannel, { - handler: function(v, e) { - console.error("MODDATA:", e.data); - if (confMan.params.onBroadcast) { - confMan.params.onBroadcast(verto, confMan, e.data); - } - if (!confMan.destroyed && confMan.params.displayID) { - $(confMan.params.displayID).html(e.data.response + "

"); - if (confMan.lastTimeout) { - clearTimeout(confMan.lastTimeout); - confMan.lastTimeout = 0; - } - confMan.lastTimeout = setTimeout(function() { $(confMan.params.displayID).html(confMan.destroyed ? "" : "Moderator Controls Ready

")}, 4000); - } + if (confMan.params.laData.role === "moderator") { + atitle = "Action"; + awidth = 200; - } - }); - - } - - var row_callback = null; + if (confMan.params.mainModID) { + genMainMod($(confMan.params.mainModID)); + $(confMan.params.displayID).html("Moderator Controls Ready

") + } else { + $(confMan.params.mainModID).html(""); + } - if (confMan.params.laData.role === "moderator") { - row_callback = function(nRow, aData, iDisplayIndex, iDisplayIndexFull) { - if (!aData[5]) { - var $row = $('td:eq(5)', nRow); - genControls($row, aData); - - if (confMan.params.onLaRow) { - confMan.params.onLaRow(verto, confMan, $row, aData); - } + verto.subscribe(confMan.params.laData.modChannel, { + handler: function(v, e) { + console.error("MODDATA:", e.data); + if (confMan.params.onBroadcast) { + confMan.params.onBroadcast(verto, confMan, e.data); + } + if (!confMan.destroyed && confMan.params.displayID) { + $(confMan.params.displayID).html(e.data.response + "

"); + if (confMan.lastTimeout) { + clearTimeout(confMan.lastTimeout); + confMan.lastTimeout = 0; + } + confMan.lastTimeout = setTimeout(function() { $(confMan.params.displayID).html(confMan.destroyed ? "" : "Moderator Controls Ready

")}, 4000); + } + } + }); + } + + var row_callback = null; + + if (confMan.params.laData.role === "moderator") { + row_callback = function(nRow, aData, iDisplayIndex, iDisplayIndexFull) { + if (!aData[5]) { + var $row = $('td:eq(5)', nRow); + genControls($row, aData); + + if (confMan.params.onLaRow) { + confMan.params.onLaRow(verto, confMan, $row, aData); + } + } + }; + } - } - }; - } - confMan.lt = new $.verto.liveTable(verto, confMan.params.laData.laChannel, confMan.params.laData.laName, $(confMan.params.tableID), { subParams: { callID: confMan.params.dialog ? confMan.params.dialog.callID : null }, - - + "onChange": function(obj, args) { $(confMan.params.statusID).text("Conference Members: " + " (" + obj.arrayLen() + " Total)"); - if (confMan.params.onLaChange) { - confMan.params.onLaChange(verto, confMan, $.verto.enum.confEvent.laChange, obj, args); - } + if (confMan.params.onLaChange) { + confMan.params.onLaChange(verto, confMan, $.verto.enum.confEvent.laChange, obj, args); + } }, "aaData": [], - "aoColumns": [{ - "sTitle": "ID" - }, - { - "sTitle": "Number" - }, - { - "sTitle": "Name" - }, - { - "sTitle": "Codec" - }, - { - "sTitle": "Status", - "sWidth": confMan.params.hasVid ? "300px" : "150px" - }, - { - "sTitle": atitle, - "sWidth": awidth, - - }], + "aoColumns": [ + { + "sTitle": "ID" + }, + { + "sTitle": "Number" + }, + { + "sTitle": "Name" + }, + { + "sTitle": "Codec" + }, + { + "sTitle": "Status", + "sWidth": confMan.params.hasVid ? "300px" : "150px" + }, + { + "sTitle": atitle, + "sWidth": awidth, + } + ], "bAutoWidth": true, "bDestroy": true, "bSort": false, @@ -1356,41 +1346,41 @@ "sEmptyTable": "The Conference is Empty....." }, - "fnRowCallback": row_callback + "fnRowCallback": row_callback }); } $.verto.confMan.prototype.modCommand = function(cmd, id, value) { - var confMan = this; - - confMan.verto.sendMethod("verto.broadcast", { - "eventChannel": confMan.params.laData.modChannel, - "data": { - "application": "conf-control", - "command": cmd, - "id": id, - "value": value - } - }); + var confMan = this; + + confMan.verto.sendMethod("verto.broadcast", { + "eventChannel": confMan.params.laData.modChannel, + "data": { + "application": "conf-control", + "command": cmd, + "id": id, + "value": value + } + }); } $.verto.confMan.prototype.destroy = function() { - var confMan = this; + var confMan = this; - confMan.destroyed = true; + confMan.destroyed = true; - if (confMan.lt) { - confMan.lt.destroy(); - } + if (confMan.lt) { + confMan.lt.destroy(); + } - if (confMan.params.laData.modChannel) { - confMan.verto.unsubscribe(confMan.params.laData.modChannel); - } + if (confMan.params.laData.modChannel) { + confMan.verto.unsubscribe(confMan.params.laData.modChannel); + } - if (confMan.params.mainModID) { - $(confMan.params.mainModID).html(""); - } + if (confMan.params.mainModID) { + $(confMan.params.mainModID).html(""); + } } $.verto.dialog = function(direction, verto, params) { @@ -1400,9 +1390,8 @@ useVideo: verto.options.useVideo, useStereo: verto.options.useStereo, tag: verto.options.tag, - login: verto.options.login - }, - params); + login: verto.options.login + }, params); dialog.verto = verto; dialog.direction = direction; @@ -1431,13 +1420,13 @@ var RTCcallbacks = {}; if (dialog.direction == $.verto.enum.direction.inbound) { - if (dialog.params.display_direction === "outbound") { - dialog.params.remote_caller_id_name = dialog.params.caller_id_name; - dialog.params.remote_caller_id_number = dialog.params.caller_id_number; - } else { - dialog.params.remote_caller_id_name = dialog.params.callee_id_name; - dialog.params.remote_caller_id_number = dialog.params.callee_id_number; - } + if (dialog.params.display_direction === "outbound") { + dialog.params.remote_caller_id_name = dialog.params.caller_id_name; + dialog.params.remote_caller_id_number = dialog.params.caller_id_number; + } else { + dialog.params.remote_caller_id_name = dialog.params.callee_id_name; + dialog.params.remote_caller_id_number = dialog.params.callee_id_number; + } if (!dialog.params.remote_caller_id_name) { dialog.params.remote_caller_id_name = "Nobody"; @@ -1469,14 +1458,13 @@ dialog.sendMethod("verto.invite", { sdp: rtc.mediaData.SDP }); - } else { //answer + } else { //answer dialog.setState($.verto.enum.state.answering); dialog.sendMethod(dialog.attach ? "verto.attach" : "verto.answer", { sdp: dialog.rtc.mediaData.SDP }); } - }; RTCcallbacks.onICE = function(rtc) { @@ -1485,7 +1473,6 @@ console.log("offer", rtc.mediaData.candidate); return; } - }; RTCcallbacks.onError = function(e) { @@ -1500,7 +1487,7 @@ useStereo: dialog.params.useStereo, videoParams: verto.options.videoParams, audioParams: verto.options.audioParams, - iceServers: verto.options.iceServers + iceServers: verto.options.iceServers }); dialog.rtc.verto = dialog.verto; @@ -1570,14 +1557,14 @@ dialog.lastState = dialog.state; dialog.state = state; - - if (!dialog.causeCode) { - dialog.causeCode = 16; - } - if (!dialog.cause) { - dialog.cause = "NORMAL CLEARING"; - } + if (!dialog.causeCode) { + dialog.causeCode = 16; + } + + if (!dialog.cause) { + dialog.cause = "NORMAL CLEARING"; + } if (dialog.callbacks.onDialogState) { dialog.callbacks.onDialogState(this); @@ -1585,12 +1572,12 @@ switch (dialog.state) { case $.verto.enum.state.trying: - setTimeout(function() { + setTimeout(function() { if (dialog.state == $.verto.enum.state.trying) { - dialog.setState($.verto.enum.state.hangup); + dialog.setState($.verto.enum.state.hangup); } }, 30000); - break; + break; case $.verto.enum.state.purge: dialog.setState($.verto.enum.state.destroy); break; @@ -1603,7 +1590,7 @@ dialog.setState($.verto.enum.state.destroy); break; case $.verto.enum.state.destroy: - delete dialog.verto.dialogs[dialog.callID]; + delete dialog.verto.dialogs[dialog.callID]; dialog.rtc.stop(); break; } @@ -1664,15 +1651,15 @@ $.verto.dialog.prototype.hangup = function(params) { var dialog = this; - if (params) { - if (params.causeCode) { - dialog.causeCode = params.causeCode; - } - - if (params.cause) { - dialog.cause = params.cause; - } - } + if (params) { + if (params.causeCode) { + dialog.causeCode = params.causeCode; + } + + if (params.cause) { + dialog.cause = params.cause; + } + } if (dialog.state.val > $.verto.enum.state.new.val && dialog.state.val < $.verto.enum.state.hangup.val) { dialog.setState($.verto.enum.state.hangup); @@ -1784,7 +1771,7 @@ var dialog = this; var err = 0; - msg.from = dialog.params.login; + msg.from = dialog.params.login; if (!msg.to) { console.error("Missing To"); @@ -1815,8 +1802,8 @@ if (params.useVideo) { dialog.useVideo(true); } - dialog.params.callee_id_name = params.callee_id_name; - dialog.params.callee_id_number = params.callee_id_number; + dialog.params.callee_id_name = params.callee_id_name; + dialog.params.callee_id_number = params.callee_id_number; } dialog.rtc.createAnswer(dialog.params.sdp); dialog.answered = true; @@ -1826,7 +1813,7 @@ $.verto.dialog.prototype.handleAnswer = function(params) { var dialog = this; - dialog.gotAnswer = true; + dialog.gotAnswer = true; if (dialog.state.val >= $.verto.enum.state.active.val) { return; @@ -1835,20 +1822,19 @@ if (dialog.state.val >= $.verto.enum.state.early.val) { dialog.setState($.verto.enum.state.active); } else { - if (dialog.gotEarly) { - console.log("Dialog " + dialog.callID + "Got answer while still establishing early media, delaying..."); - } else { - console.log("Dialog " + dialog.callID + "Answering Channel"); - dialog.rtc.answer(params.sdp, function() { + if (dialog.gotEarly) { + console.log("Dialog " + dialog.callID + "Got answer while still establishing early media, delaying..."); + } else { + console.log("Dialog " + dialog.callID + "Answering Channel"); + dialog.rtc.answer(params.sdp, function() { dialog.setState($.verto.enum.state.active); - }, - function(e) { - console.error(e); - dialog.hangup(); - }); - console.log("Dialog " + dialog.callID + "ANSWER SDP", params.sdp); + }, function(e) { + console.error(e); + dialog.hangup(); + }); + console.log("Dialog " + dialog.callID + "ANSWER SDP", params.sdp); } - } + } }; $.verto.dialog.prototype.cidString = function(enc) { @@ -1891,18 +1877,17 @@ return; } - dialog.gotEarly = true; - - dialog.rtc.answer(params.sdp, function() { - console.log("Dialog " + dialog.callID + "Establishing early media"); - dialog.setState($.verto.enum.state.early); + dialog.gotEarly = true; - if (dialog.gotAnswer) { - console.log("Dialog " + dialog.callID + "Answering Channel"); - dialog.setState($.verto.enum.state.active); - } - }, - function(e) { + dialog.rtc.answer(params.sdp, function() { + console.log("Dialog " + dialog.callID + "Establishing early media"); + dialog.setState($.verto.enum.state.early); + + if (dialog.gotAnswer) { + console.log("Dialog " + dialog.callID + "Answering Channel"); + dialog.setState($.verto.enum.state.active); + } + }, function(e) { console.error(e); dialog.hangup(); }); @@ -1926,7 +1911,7 @@ $.verto.enum.states = Object.freeze({ new: { requesting: 1, - recovering: 1, + recovering: 1, ringing: 1, destroy: 1, answering: 1 @@ -1953,8 +1938,8 @@ hangup: 1 }, active: { - answering: 1, - requesting: 1, + answering: 1, + requesting: 1, hangup: 1, held: 1 },