Add new features to JavaScript Server class

Add ability to remove periodically called functions and to
unregister api functions(that can be called by the server)
This commit is contained in:
Dmitriy Simushev 2013-02-14 09:32:30 +00:00
parent 48cc52cf72
commit dee2f2ada7
3 changed files with 81 additions and 28 deletions

View File

@ -5,10 +5,11 @@
Copyright (c) 2005-2011 Mibew Messenger Community Copyright (c) 2005-2011 Mibew Messenger Community
License: http://mibew.org/license.php License: http://mibew.org/license.php
*/ */
(function(b,g,h,d){b.Server=function(a){this.updateTimer=null;this.options=d.extend({url:"",requestsFrequency:2,reconnectPause:1,onTimeout:function(){},onTransportError:function(){},onCallError:function(){},onUpdateError:function(){},onResponseError:function(){}},a);this.callbacks={};this.callPeriodically=[];this.ajaxRequest=null;this.buffer=[];this.functions={};this.mibewAPI=new g(new this.options.interactionType)};b.Server.prototype.callFunctions=function(a,e,b){try{if(!(a instanceof Array))throw Error("The first arguments must be an array"); (function(b,f,g,e){b.Server=function(a){this.updateTimer=null;this.options=e.extend({url:"",requestsFrequency:2,reconnectPause:1,onTimeout:function(){},onTransportError:function(){},onCallError:function(){},onUpdateError:function(){},onResponseError:function(){}},a);this.callbacks={};this.callPeriodically={};this.callPeriodicallyLastId=0;this.ajaxRequest=null;this.buffer=[];this.functions={};this.functionsLastId=0;this.mibewAPI=new f(new this.options.interactionType)};b.Server.prototype.callFunctions=
for(var c in a)a.hasOwnProperty(c)&&this.mibewAPI.checkFunction(a[c],!1);var f=this.generateToken();this.callbacks[f]=e;this.buffer.push({token:f,functions:a});b&&this.update()}catch(d){return this.options.onCallError(d),!1}return!0};b.Server.prototype.callFunctionsPeriodically=function(a,e){this.callPeriodically.push({functionsListBuilder:a,callbackFunction:e})};b.Server.prototype.generateToken=function(){var a;do a="wnd"+(new Date).getTime().toString()+Math.round(50*Math.random()).toString();while(a in function(a,c,b){try{if(!(a instanceof Array))throw Error("The first arguments must be an array");for(var d=0;d<a.length;d++)this.mibewAPI.checkFunction(a[d],!1);var e=this.generateToken();this.callbacks[e]=c;this.buffer.push({token:e,functions:a});b&&this.update()}catch(f){return this.options.onCallError(f),!1}return!0};b.Server.prototype.callFunctionsPeriodically=function(a,c){this.callPeriodicallyLastId++;this.callPeriodically[this.callPeriodicallyLastId]={functionsListBuilder:a,callbackFunction:c};
this.callbacks);return a};b.Server.prototype.processRequest=function(a){var e=new MibewAPIExecutionContext,b=this.mibewAPI.getResultFunction(a.functions,this.callbacks.hasOwnProperty(a.token));if(null===b)for(var c in a.functions)a.functions.hasOwnProperty(c)&&(this.processFunction(a.functions[c],e),this.buffer.push(this.mibewAPI.buildResult(e.getResults(),a.token)));else this.callbacks.hasOwnProperty(a.token)&&(this.callbacks[a.token](b.arguments),delete this.callbacks[a.token])};b.Server.prototype.processFunction= return this.callPeriodicallyLastId};b.Server.prototype.stopCallFunctionsPeriodically=function(a){a in this.callPeriodically&&delete this.callPeriodically[a]};b.Server.prototype.generateToken=function(){var a;do a="wnd"+(new Date).getTime().toString()+Math.round(50*Math.random()).toString();while(a in this.callbacks);return a};b.Server.prototype.processRequest=function(a){var c=new MibewAPIExecutionContext,b=this.mibewAPI.getResultFunction(a.functions,this.callbacks.hasOwnProperty(a.token));if(null===
function(a,e){if(this.functions.hasOwnProperty(a["function"])){var b=e.getArgumentsList(a),c={},f;for(f in this.functions[a["function"]])this.functions[a["function"]].hasOwnProperty(f)&&(c=d.extend(c,this.functions[a["function"]][f](b)));e.storeFunctionResults(a,c)}};b.Server.prototype.sendRequests=function(a){this.ajaxRequest=h.ajax({url:this.options.url,timeout:5E3,async:!0,cache:!1,type:"POST",dataType:"text",data:{data:this.mibewAPI.encodePackage(a)},success:d.bind(this.receiveResponse,this), b)for(var d in a.functions)a.functions.hasOwnProperty(d)&&(this.processFunction(a.functions[d],c),this.buffer.push(this.mibewAPI.buildResult(c.getResults(),a.token)));else this.callbacks.hasOwnProperty(a.token)&&(this.callbacks[a.token](b.arguments),delete this.callbacks[a.token])};b.Server.prototype.processFunction=function(a,c){if(this.functions.hasOwnProperty(a["function"])){var b=c.getArgumentsList(a),d={},f;for(f in this.functions[a["function"]])this.functions[a["function"]].hasOwnProperty(f)&&
error:d.bind(this.onError,this)})};b.Server.prototype.runUpdater=function(){this.update()};b.Server.prototype.updateAfter=function(a){this.updateTimer=setTimeout(d.bind(this.update,this),1E3*a)};b.Server.prototype.restartUpdater=function(){this.updateTimer&&clearTimeout(this.updateTimer);this.ajaxRequest&&this.ajaxRequest.abort();this.updateAfter(this.options.reconnectPause)};b.Server.prototype.update=function(){this.updateTimer&&clearTimeout(this.updateTimer);for(var a=0;a<this.callPeriodically.length;a++)this.callFunctions(this.callPeriodically[a].functionsListBuilder(), (d=e.extend(d,this.functions[a["function"]][f](b)));c.storeFunctionResults(a,d)}};b.Server.prototype.sendRequests=function(a){this.ajaxRequest=g.ajax({url:this.options.url,timeout:5E3,async:!0,cache:!1,type:"POST",dataType:"text",data:{data:this.mibewAPI.encodePackage(a)},success:e.bind(this.receiveResponse,this),error:e.bind(this.onError,this)})};b.Server.prototype.runUpdater=function(){this.update()};b.Server.prototype.updateAfter=function(a){this.updateTimer=setTimeout(e.bind(this.update,this),
this.callPeriodically[a].callbackFunction);if(0==this.buffer.length)this.updateAfter(this.options.requestsFrequency);else try{this.sendRequests(this.buffer),this.buffer=[]}catch(b){this.options.onUpdateError(b)}};b.Server.prototype.receiveResponse=function(a){""==a&&this.updateAfter(this.options.requestsFrequency);try{var b=this.mibewAPI.decodePackage(a),d;for(d in b.requests)this.processRequest(b.requests[d])}catch(c){this.options.onResponseError(c)}finally{this.updateAfter(this.options.requestsFrequency)}}; 1E3*a)};b.Server.prototype.restartUpdater=function(){this.updateTimer&&clearTimeout(this.updateTimer);this.ajaxRequest&&this.ajaxRequest.abort();this.updateAfter(this.options.reconnectPause)};b.Server.prototype.update=function(){this.updateTimer&&clearTimeout(this.updateTimer);for(var a in this.callPeriodically)this.callPeriodically.hasOwnProperty(a)&&this.callFunctions(this.callPeriodically[a].functionsListBuilder(),this.callPeriodically[a].callbackFunction);if(0==this.buffer.length)this.updateAfter(this.options.requestsFrequency);
b.Server.prototype.registerFunction=function(a,b){a in this.functions||(this.functions[a]=[]);this.functions[a].push(b)};b.Server.prototype.onError=function(a,b){if("abort"!=b)if(this.restartUpdater(),"timeout"==b)this.options.onTimeout();else if("error"==b)this.options.onTransportError()}})(Mibew,MibewAPI,$,_); else try{this.sendRequests(this.buffer),this.buffer=[]}catch(c){this.options.onUpdateError(c)}};b.Server.prototype.receiveResponse=function(a){""==a&&this.updateAfter(this.options.requestsFrequency);try{var c=this.mibewAPI.decodePackage(a),b;for(b in c.requests)this.processRequest(c.requests[b])}catch(d){this.options.onResponseError(d)}finally{this.updateAfter(this.options.requestsFrequency)}};b.Server.prototype.registerFunction=function(a,b){this.functionsLastId++;a in this.functions||(this.functions[a]=
{});this.functions[a][this.functionsLastId]=b;return this.functionsLastId};b.Server.prototype.unregisterFunction=function(a){for(var b in this.functions)this.functions.hasOwnProperty(b)&&(a in this.functions[b]&&delete this.functions[b][a],e.isEmpty(this.functions[b])&&delete this.functions[b])};b.Server.prototype.onError=function(a,b){if("abort"!=b)if(this.restartUpdater(),"timeout"==b)this.options.onTimeout();else if("error"==b)this.options.onTransportError()}})(Mibew,MibewAPI,$,_);

View File

@ -33,13 +33,14 @@ return new b.SafeString(a)});b.registerHelper("formatTime",function(a){var c=new
Copyright (c) 2005-2011 Mibew Messenger Community Copyright (c) 2005-2011 Mibew Messenger Community
License: http://mibew.org/license.php License: http://mibew.org/license.php
*/ */
(function(b,g,h,d){b.Server=function(a){this.updateTimer=null;this.options=d.extend({url:"",requestsFrequency:2,reconnectPause:1,onTimeout:function(){},onTransportError:function(){},onCallError:function(){},onUpdateError:function(){},onResponseError:function(){}},a);this.callbacks={};this.callPeriodically=[];this.ajaxRequest=null;this.buffer=[];this.functions={};this.mibewAPI=new g(new this.options.interactionType)};b.Server.prototype.callFunctions=function(a,e,b){try{if(!(a instanceof Array))throw Error("The first arguments must be an array"); (function(b,f,g,e){b.Server=function(a){this.updateTimer=null;this.options=e.extend({url:"",requestsFrequency:2,reconnectPause:1,onTimeout:function(){},onTransportError:function(){},onCallError:function(){},onUpdateError:function(){},onResponseError:function(){}},a);this.callbacks={};this.callPeriodically={};this.callPeriodicallyLastId=0;this.ajaxRequest=null;this.buffer=[];this.functions={};this.functionsLastId=0;this.mibewAPI=new f(new this.options.interactionType)};b.Server.prototype.callFunctions=
for(var c in a)a.hasOwnProperty(c)&&this.mibewAPI.checkFunction(a[c],!1);var f=this.generateToken();this.callbacks[f]=e;this.buffer.push({token:f,functions:a});b&&this.update()}catch(d){return this.options.onCallError(d),!1}return!0};b.Server.prototype.callFunctionsPeriodically=function(a,e){this.callPeriodically.push({functionsListBuilder:a,callbackFunction:e})};b.Server.prototype.generateToken=function(){var a;do a="wnd"+(new Date).getTime().toString()+Math.round(50*Math.random()).toString();while(a in function(a,c,b){try{if(!(a instanceof Array))throw Error("The first arguments must be an array");for(var d=0;d<a.length;d++)this.mibewAPI.checkFunction(a[d],!1);var e=this.generateToken();this.callbacks[e]=c;this.buffer.push({token:e,functions:a});b&&this.update()}catch(f){return this.options.onCallError(f),!1}return!0};b.Server.prototype.callFunctionsPeriodically=function(a,c){this.callPeriodicallyLastId++;this.callPeriodically[this.callPeriodicallyLastId]={functionsListBuilder:a,callbackFunction:c};
this.callbacks);return a};b.Server.prototype.processRequest=function(a){var e=new MibewAPIExecutionContext,b=this.mibewAPI.getResultFunction(a.functions,this.callbacks.hasOwnProperty(a.token));if(null===b)for(var c in a.functions)a.functions.hasOwnProperty(c)&&(this.processFunction(a.functions[c],e),this.buffer.push(this.mibewAPI.buildResult(e.getResults(),a.token)));else this.callbacks.hasOwnProperty(a.token)&&(this.callbacks[a.token](b.arguments),delete this.callbacks[a.token])};b.Server.prototype.processFunction= return this.callPeriodicallyLastId};b.Server.prototype.stopCallFunctionsPeriodically=function(a){a in this.callPeriodically&&delete this.callPeriodically[a]};b.Server.prototype.generateToken=function(){var a;do a="wnd"+(new Date).getTime().toString()+Math.round(50*Math.random()).toString();while(a in this.callbacks);return a};b.Server.prototype.processRequest=function(a){var c=new MibewAPIExecutionContext,b=this.mibewAPI.getResultFunction(a.functions,this.callbacks.hasOwnProperty(a.token));if(null===
function(a,e){if(this.functions.hasOwnProperty(a["function"])){var b=e.getArgumentsList(a),c={},f;for(f in this.functions[a["function"]])this.functions[a["function"]].hasOwnProperty(f)&&(c=d.extend(c,this.functions[a["function"]][f](b)));e.storeFunctionResults(a,c)}};b.Server.prototype.sendRequests=function(a){this.ajaxRequest=h.ajax({url:this.options.url,timeout:5E3,async:!0,cache:!1,type:"POST",dataType:"text",data:{data:this.mibewAPI.encodePackage(a)},success:d.bind(this.receiveResponse,this), b)for(var d in a.functions)a.functions.hasOwnProperty(d)&&(this.processFunction(a.functions[d],c),this.buffer.push(this.mibewAPI.buildResult(c.getResults(),a.token)));else this.callbacks.hasOwnProperty(a.token)&&(this.callbacks[a.token](b.arguments),delete this.callbacks[a.token])};b.Server.prototype.processFunction=function(a,c){if(this.functions.hasOwnProperty(a["function"])){var b=c.getArgumentsList(a),d={},f;for(f in this.functions[a["function"]])this.functions[a["function"]].hasOwnProperty(f)&&
error:d.bind(this.onError,this)})};b.Server.prototype.runUpdater=function(){this.update()};b.Server.prototype.updateAfter=function(a){this.updateTimer=setTimeout(d.bind(this.update,this),1E3*a)};b.Server.prototype.restartUpdater=function(){this.updateTimer&&clearTimeout(this.updateTimer);this.ajaxRequest&&this.ajaxRequest.abort();this.updateAfter(this.options.reconnectPause)};b.Server.prototype.update=function(){this.updateTimer&&clearTimeout(this.updateTimer);for(var a=0;a<this.callPeriodically.length;a++)this.callFunctions(this.callPeriodically[a].functionsListBuilder(), (d=e.extend(d,this.functions[a["function"]][f](b)));c.storeFunctionResults(a,d)}};b.Server.prototype.sendRequests=function(a){this.ajaxRequest=g.ajax({url:this.options.url,timeout:5E3,async:!0,cache:!1,type:"POST",dataType:"text",data:{data:this.mibewAPI.encodePackage(a)},success:e.bind(this.receiveResponse,this),error:e.bind(this.onError,this)})};b.Server.prototype.runUpdater=function(){this.update()};b.Server.prototype.updateAfter=function(a){this.updateTimer=setTimeout(e.bind(this.update,this),
this.callPeriodically[a].callbackFunction);if(0==this.buffer.length)this.updateAfter(this.options.requestsFrequency);else try{this.sendRequests(this.buffer),this.buffer=[]}catch(b){this.options.onUpdateError(b)}};b.Server.prototype.receiveResponse=function(a){""==a&&this.updateAfter(this.options.requestsFrequency);try{var b=this.mibewAPI.decodePackage(a),d;for(d in b.requests)this.processRequest(b.requests[d])}catch(c){this.options.onResponseError(c)}finally{this.updateAfter(this.options.requestsFrequency)}}; 1E3*a)};b.Server.prototype.restartUpdater=function(){this.updateTimer&&clearTimeout(this.updateTimer);this.ajaxRequest&&this.ajaxRequest.abort();this.updateAfter(this.options.reconnectPause)};b.Server.prototype.update=function(){this.updateTimer&&clearTimeout(this.updateTimer);for(var a in this.callPeriodically)this.callPeriodically.hasOwnProperty(a)&&this.callFunctions(this.callPeriodically[a].functionsListBuilder(),this.callPeriodically[a].callbackFunction);if(0==this.buffer.length)this.updateAfter(this.options.requestsFrequency);
b.Server.prototype.registerFunction=function(a,b){a in this.functions||(this.functions[a]=[]);this.functions[a].push(b)};b.Server.prototype.onError=function(a,b){if("abort"!=b)if(this.restartUpdater(),"timeout"==b)this.options.onTimeout();else if("error"==b)this.options.onTransportError()}})(Mibew,MibewAPI,$,_); else try{this.sendRequests(this.buffer),this.buffer=[]}catch(c){this.options.onUpdateError(c)}};b.Server.prototype.receiveResponse=function(a){""==a&&this.updateAfter(this.options.requestsFrequency);try{var c=this.mibewAPI.decodePackage(a),b;for(b in c.requests)this.processRequest(c.requests[b])}catch(d){this.options.onResponseError(d)}finally{this.updateAfter(this.options.requestsFrequency)}};b.Server.prototype.registerFunction=function(a,b){this.functionsLastId++;a in this.functions||(this.functions[a]=
{});this.functions[a][this.functionsLastId]=b;return this.functionsLastId};b.Server.prototype.unregisterFunction=function(a){for(var b in this.functions)this.functions.hasOwnProperty(b)&&(a in this.functions[b]&&delete this.functions[b][a],e.isEmpty(this.functions[b])&&delete this.functions[b])};b.Server.prototype.onError=function(a,b){if("abort"!=b)if(this.restartUpdater(),"timeout"==b)this.options.onTimeout();else if("error"==b)this.options.onTransportError()}})(Mibew,MibewAPI,$,_);
/* /*
This file is part of Mibew Messenger project. This file is part of Mibew Messenger project.
http://mibew.org http://mibew.org

View File

@ -51,11 +51,18 @@
this.callbacks = {}; this.callbacks = {};
/** /**
* Array of periodically called functions * Contains periodically called functions
* @type Array * @type Object
* @private * @private
*/ */
this.callPeriodically = []; this.callPeriodically = {};
/**
* Id of the last added periodically called function
* @type Number
* @private
*/
this.callPeriodicallyLastId = 0;
/** /**
* An object of the jqXHR class * An object of the jqXHR class
@ -72,10 +79,18 @@
/** /**
* Contains object of registered functions handlers * Contains object of registered functions handlers
* @type Object
* @private * @private
*/ */
this.functions = {} this.functions = {}
/**
* Id of the last registered function
* @type Number
* @private
*/
this.functionsLastId = 0;
/** /**
* An instance of the MibewAPI class * An instance of the MibewAPI class
* @type MibewAPI * @type MibewAPI
@ -99,12 +114,7 @@
if (!(functionsList instanceof Array)) { if (!(functionsList instanceof Array)) {
throw new Error("The first arguments must be an array"); throw new Error("The first arguments must be an array");
} }
// TODO: Try to use 'for' loop instead of 'for in' loop for (var i = 0; i < functionsList.length; i++) {
for (var i in functionsList) {
// Filter 'Prototype' properties
if (! functionsList.hasOwnProperty(i)) {
continue;
}
this.mibewAPI.checkFunction(functionsList[i], false); this.mibewAPI.checkFunction(functionsList[i], false);
} }
@ -136,12 +146,27 @@
* @param {Function} functionsListBuilder Call before every request to build * @param {Function} functionsListBuilder Call before every request to build
* a list of functions that must be called * a list of functions that must be called
* @param {Function} callbackFunction Call after response received * @param {Function} callbackFunction Call after response received
* @returns {Number} Id of added functions
*/ */
Mibew.Server.prototype.callFunctionsPeriodically = function(functionsListBuilder, callbackFunction) { Mibew.Server.prototype.callFunctionsPeriodically = function(functionsListBuilder, callbackFunction) {
this.callPeriodically.push({ this.callPeriodicallyLastId++;
this.callPeriodically[this.callPeriodicallyLastId] = {
functionsListBuilder: functionsListBuilder, functionsListBuilder: functionsListBuilder,
callbackFunction: callbackFunction callbackFunction: callbackFunction
}); };
return this.callPeriodicallyLastId;
}
/**
* Stop calling function at every request.
*
* @param {Number} id Id of the periodically called function, returned by
* Mibew.Server.callFunctionsPeriodically method
*/
Mibew.Server.prototype.stopCallFunctionsPeriodically = function(id) {
if (id in this.callPeriodically) {
delete this.callPeriodically[id];
}
} }
/** /**
@ -301,7 +326,10 @@
if (this.updateTimer) { if (this.updateTimer) {
clearTimeout(this.updateTimer); clearTimeout(this.updateTimer);
} }
for (var i = 0; i < this.callPeriodically.length; i++) { for (var i in this.callPeriodically) {
if (! this.callPeriodically.hasOwnProperty(i)) {
continue;
}
this.callFunctions( this.callFunctions(
this.callPeriodically[i].functionsListBuilder(), this.callPeriodically[i].functionsListBuilder(),
this.callPeriodically[i].callbackFunction this.callPeriodically[i].callbackFunction
@ -356,14 +384,37 @@
* *
* @param {String} functionName Name of the function * @param {String} functionName Name of the function
* @param {Function} handler Provided function * @param {Function} handler Provided function
* @returns {Number} Id of registered function
*/ */
Mibew.Server.prototype.registerFunction = function(functionName, handler) { Mibew.Server.prototype.registerFunction = function(functionName, handler) {
this.functionsLastId++;
if (!(functionName in this.functions)) { if (!(functionName in this.functions)) {
this.functions[functionName] = []; this.functions[functionName] = {};
} }
this.functions[functionName].push(handler); this.functions[functionName][this.functionsLastId] = handler;
return this.functionsLastId;
} }
/**
* Remove function that can be called by Server
*
* @param {Number} id Id of function returned by
* Mibew.Server.registerFunction method
*/
Mibew.Server.prototype.unregisterFunction = function(id) {
for (var i in this.functions) {
if (! this.functions.hasOwnProperty(i)) {
continue;
}
if (id in this.functions[i]) {
delete this.functions[i][id];
}
if (_.isEmpty(this.functions[i])) {
delete this.functions[i];
}
}
},
/** /**
* Call on AJAX errors * Call on AJAX errors
* *