mirror of
https://github.com/Mibew/java.git
synced 2025-01-23 01:50:34 +03:00
Move JavaScript's ChatServer class to separate file
This commit is contained in:
parent
83636a02ef
commit
d53e1d8020
@ -7,14 +7,7 @@
|
|||||||
*/
|
*/
|
||||||
var FrameUtils={getDocument:function(a){return a.contentDocument?a.contentDocument:a.contentWindow?a.contentWindow.document:a.document?a.document:null},initFrame:function(a){var b=this.getDocument(a);b.open();b.write("<html><head>");b.write('<link rel="stylesheet" type="text/css" media="all" href="'+Chat.cssfile+'">');b.write("</head><body bgcolor='#FFFFFF' text='#000000' link='#C28400' vlink='#C28400' alink='#C28400'>");b.write("<table width='100%' cellspacing='0' cellpadding='0' border='0'><tr><td valign='top' class='message' id='content'></td></tr></table><a id='bottom' name='bottom'></a>");
|
var FrameUtils={getDocument:function(a){return a.contentDocument?a.contentDocument:a.contentWindow?a.contentWindow.document:a.document?a.document:null},initFrame:function(a){var b=this.getDocument(a);b.open();b.write("<html><head>");b.write('<link rel="stylesheet" type="text/css" media="all" href="'+Chat.cssfile+'">');b.write("</head><body bgcolor='#FFFFFF' text='#000000' link='#C28400' vlink='#C28400' alink='#C28400'>");b.write("<table width='100%' cellspacing='0' cellpadding='0' border='0'><tr><td valign='top' class='message' id='content'></td></tr></table><a id='bottom' name='bottom'></a>");
|
||||||
b.write("</body></html>");b.close();a.onload=function(){a.myHtml&&(FrameUtils.getDocument(a).getElementById("content").innerHTML+=a.myHtml,FrameUtils.scrollDown(a))}},insertIntoFrame:function(a,b){var c=this.getDocument(a).getElementById("content");null==c?(a.myHtml||(a.myHtml=""),a.myHtml+=b):c.innerHTML+=b},scrollDown:function(a){var b=this.getDocument(a).getElementById("bottom");if("opera"==myAgent)try{a.contentWindow.scrollTo(0,this.getDocument(a).getElementById("content").clientHeight)}catch(c){}b&&
|
b.write("</body></html>");b.close();a.onload=function(){a.myHtml&&(FrameUtils.getDocument(a).getElementById("content").innerHTML+=a.myHtml,FrameUtils.scrollDown(a))}},insertIntoFrame:function(a,b){var c=this.getDocument(a).getElementById("content");null==c?(a.myHtml||(a.myHtml=""),a.myHtml+=b):c.innerHTML+=b},scrollDown:function(a){var b=this.getDocument(a).getElementById("bottom");if("opera"==myAgent)try{a.contentWindow.scrollTo(0,this.getDocument(a).getElementById("content").clientHeight)}catch(c){}b&&
|
||||||
b.scrollIntoView(!1)}};ChatServer=Class.create();
|
b.scrollIntoView(!1)}};ChatThreadUpdater=Class.create();
|
||||||
ChatServer.prototype={initialize:function(a){this.updateTimer=null;this.options={servl:"",requestsFrequency:2,onTimeout:function(){},onTransportError:function(){},onCallError:function(){},onUpdateError:function(){},onResponseError:function(){}}.extend(a);this.callbacks={};this.callPeriodically=[];this.ajaxOptions={_method:"post",asynchronous:!0,timeout:5E3,onComplete:this.receiveResponse.bind(this),onException:this.onTransportError.bind(this),onTimeout:this.onTimeout.bind(this)};this.ajaxRequest=
|
|
||||||
null;this.buffer=[];this.functions={};this.mibewAPI=new MibewAPI(new MibewAPICoreInteraction)},callFunctions:function(a,b,c){try{if(!(a instanceof Array))throw Error("The first arguments must be an array");for(var d in a)a.hasOwnProperty(d)&&this.mibewAPI.checkFunction(a[d],!1);var e=this.generateToken();this.callbacks[e]=b;this.buffer.push({token:e,functions:a});c&&this.update()}catch(f){return this.options.onCallError(f),!1}return!0},callFunctionsPeriodically:function(a,b){this.callPeriodically.push({functionsListBuilder:a,
|
|
||||||
callbackFunction:b})},generateToken:function(){var a;do a="wnd"+(new Date).getTime().toString()+Math.round(50*Math.random()).toString();while(a in this.callbacks);return a},processRequest:function(a){var b=new MibewAPIExecutionContext,c=this.mibewAPI.getResultFunction(a.functions,this.callbacks.hasOwnProperty(a.token));if(null===c)for(var d in a.functions)a.functions.hasOwnProperty(d)&&(this.processFunction(a.functions[d],b),this.buffer.push(this.mibewAPI.buildResult(b.getResults(),a.token)));else this.callbacks.hasOwnProperty(a.token)&&
|
|
||||||
(this.callbacks[a.token](c.arguments),delete this.callbacks[a.token])},processFunction:function(a,b){if(this.functions.hasOwnProperty(a["function"])){var c=b.getArgumentsList(a),d={},e;for(e in this.functions[a["function"]])this.functions[a["function"]].hasOwnProperty(e)&&d.extend(this.functions[a["function"]][e](c));b.storeFunctionResults(a,d)}},sendRequests:function(a){this.ajaxRequest=new Ajax.Request(this.options.servl,this.ajaxOptions.extend({parameters:"data="+this.mibewAPI.encodePackage(a)}))},
|
|
||||||
runUpdater:function(){null==this.updateTimer&&this.update();this.updateTimer=setTimeout(this.update.bind(this),1E3*this.options.requestsFrequency)},restartUpdater:function(){this.updateTimer&&clearTimeout(this.updateTimer);this.ajaxRequest._options&&(this.ajaxRequest._options.onComplete=void 0);this.update();this.updateTimer=setTimeout(this.update.bind(this),1E3)},update:function(){this.updateTimer&&clearTimeout(this.updateTimer);for(var a=0;a<this.callPeriodically.length;a++)this.callFunctions(this.callPeriodically[a].functionsListBuilder(),
|
|
||||||
this.callPeriodically[a].callbackFunction);if(0==this.buffer.length)this.runUpdater();else try{this.sendRequests(this.buffer),this.buffer=[]}catch(b){this.options.onUpdateError(b)}},receiveResponse:function(a){""==a.response&&this.runUpdater();try{var b=this.mibewAPI.decodePackage(a.response),c;for(c in b.requests)this.processRequest(b.requests[c])}catch(d){this.options.onResponseError(d)}finally{this.runUpdater()}},registerFunction:function(a,b){a in this.functions||(this.functions[a]=[]);this.functions[a].push(b)},
|
|
||||||
onTransportError:function(a,b){this.restartUpdater();this.options.onTransportError(b)},onTimeout:function(){this.restartUpdater();this.options.onTimeout()}};ChatThreadUpdater=Class.create();
|
|
||||||
ChatThreadUpdater.prototype={initialize:function(a,b,c){this._options=c;this.thread=b;this.chatServer=a;this.focused=this.skipNextsound=this.cansend=!0;this.ownThread=null!=this._options.message;FrameUtils.initFrame(this._options.container);this._options.message&&(this._options.message.onkeydown=this.handleKeyDown.bind(this),this._options.message.onfocus=function(){this.focused=!0}.bind(this),this._options.message.onblur=function(){this.focused=!1}.bind(this));this.chatServer.callFunctionsPeriodically(this.updateFunctionBuilder.bind(this),
|
ChatThreadUpdater.prototype={initialize:function(a,b,c){this._options=c;this.thread=b;this.chatServer=a;this.focused=this.skipNextsound=this.cansend=!0;this.ownThread=null!=this._options.message;FrameUtils.initFrame(this._options.container);this._options.message&&(this._options.message.onkeydown=this.handleKeyDown.bind(this),this._options.message.onfocus=function(){this.focused=!0}.bind(this),this._options.message.onblur=function(){this.focused=!1}.bind(this));this.chatServer.callFunctionsPeriodically(this.updateFunctionBuilder.bind(this),
|
||||||
this.updateChatState.bind(this));this.chatServer.registerFunction("updateMessages",this.updateMessages.bind(this));this.chatServer.registerFunction("setupAvatar",this.setupAvatar.bind(this));this.chatServer.runUpdater()},handleException:function(){this.setStatus("offline, reconnecting");this.enableInput(!0)},handleTimeout:function(){this.setStatus("timeout, reconnecting");this.enableInput(!0)},enableInput:function(a){this._options.message&&(this._options.message.disabled=!a)},refresh:function(){this.chatServer.restartUpdater()},
|
this.updateChatState.bind(this));this.chatServer.registerFunction("updateMessages",this.updateMessages.bind(this));this.chatServer.registerFunction("setupAvatar",this.setupAvatar.bind(this));this.chatServer.runUpdater()},handleException:function(){this.setStatus("offline, reconnecting");this.enableInput(!0)},handleTimeout:function(){this.setStatus("timeout, reconnecting");this.enableInput(!0)},enableInput:function(a){this._options.message&&(this._options.message.disabled=!a)},refresh:function(){this.chatServer.restartUpdater()},
|
||||||
postMessage:function(a){""!=a&&this.cansend&&(this.cansend=!1,this.skipNextsound=!0,"opera"!=myRealAgent&&this.enableInput(!1),this.chatServer.callFunctions([{"function":"post",arguments:{references:{},"return":{},message:a,threadId:this.thread.threadid,token:this.thread.token,user:this.thread.user}}],function(){this.enableInput(!0);this.cansend=!0;this.skipNextsound=!1;this._options.message&&(this._options.message.value="",this._options.message.focus())}.bind(this),!0))},changeName:function(a){this.skipNextsound=
|
postMessage:function(a){""!=a&&this.cansend&&(this.cansend=!1,this.skipNextsound=!0,"opera"!=myRealAgent&&this.enableInput(!1),this.chatServer.callFunctions([{"function":"post",arguments:{references:{},"return":{},message:a,threadId:this.thread.threadid,token:this.thread.token,user:this.thread.user}}],function(){this.enableInput(!0);this.cansend=!0;this.skipNextsound=!1;this._options.message&&(this._options.message.value="",this._options.message.focus())}.bind(this),!0))},changeName:function(a){this.skipNextsound=
|
||||||
|
15
src/messenger/webim/js/164/chatserver.js
Normal file
15
src/messenger/webim/js/164/chatserver.js
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
/*
|
||||||
|
This file is part of Mibew Messenger project.
|
||||||
|
http://mibew.org
|
||||||
|
|
||||||
|
Copyright (c) 2005-2011 Mibew Messenger Community
|
||||||
|
License: http://mibew.org/license.php
|
||||||
|
*/
|
||||||
|
ChatServer=Class.create();
|
||||||
|
ChatServer.prototype={initialize:function(a){this.updateTimer=null;this.options={servl:"",requestsFrequency:2,onTimeout:function(){},onTransportError:function(){},onCallError:function(){},onUpdateError:function(){},onResponseError:function(){}}.extend(a);this.callbacks={};this.callPeriodically=[];this.ajaxOptions={_method:"post",asynchronous:!0,timeout:5E3,onComplete:this.receiveResponse.bind(this),onException:this.onTransportError.bind(this),onTimeout:this.onTimeout.bind(this)};this.ajaxRequest=
|
||||||
|
null;this.buffer=[];this.functions={};this.mibewAPI=new MibewAPI(new MibewAPICoreInteraction)},callFunctions:function(a,b,d){try{if(!(a instanceof Array))throw Error("The first arguments must be an array");for(var c in a)a.hasOwnProperty(c)&&this.mibewAPI.checkFunction(a[c],!1);var e=this.generateToken();this.callbacks[e]=b;this.buffer.push({token:e,functions:a});d&&this.update()}catch(f){return this.options.onCallError(f),!1}return!0},callFunctionsPeriodically:function(a,b){this.callPeriodically.push({functionsListBuilder:a,
|
||||||
|
callbackFunction:b})},generateToken:function(){var a;do a="wnd"+(new Date).getTime().toString()+Math.round(50*Math.random()).toString();while(a in this.callbacks);return a},processRequest:function(a){var b=new MibewAPIExecutionContext,d=this.mibewAPI.getResultFunction(a.functions,this.callbacks.hasOwnProperty(a.token));if(null===d)for(var c in a.functions)a.functions.hasOwnProperty(c)&&(this.processFunction(a.functions[c],b),this.buffer.push(this.mibewAPI.buildResult(b.getResults(),a.token)));else this.callbacks.hasOwnProperty(a.token)&&
|
||||||
|
(this.callbacks[a.token](d.arguments),delete this.callbacks[a.token])},processFunction:function(a,b){if(this.functions.hasOwnProperty(a["function"])){var d=b.getArgumentsList(a),c={},e;for(e in this.functions[a["function"]])this.functions[a["function"]].hasOwnProperty(e)&&c.extend(this.functions[a["function"]][e](d));b.storeFunctionResults(a,c)}},sendRequests:function(a){this.ajaxRequest=new Ajax.Request(this.options.servl,this.ajaxOptions.extend({parameters:"data="+this.mibewAPI.encodePackage(a)}))},
|
||||||
|
runUpdater:function(){null==this.updateTimer&&this.update();this.updateTimer=setTimeout(this.update.bind(this),1E3*this.options.requestsFrequency)},restartUpdater:function(){this.updateTimer&&clearTimeout(this.updateTimer);this.ajaxRequest._options&&(this.ajaxRequest._options.onComplete=void 0);this.update();this.updateTimer=setTimeout(this.update.bind(this),1E3)},update:function(){this.updateTimer&&clearTimeout(this.updateTimer);for(var a=0;a<this.callPeriodically.length;a++)this.callFunctions(this.callPeriodically[a].functionsListBuilder(),
|
||||||
|
this.callPeriodically[a].callbackFunction);if(0==this.buffer.length)this.runUpdater();else try{this.sendRequests(this.buffer),this.buffer=[]}catch(b){this.options.onUpdateError(b)}},receiveResponse:function(a){""==a.response&&this.runUpdater();try{var b=this.mibewAPI.decodePackage(a.response),d;for(d in b.requests)this.processRequest(b.requests[d])}catch(c){this.options.onResponseError(c)}finally{this.runUpdater()}},registerFunction:function(a,b){a in this.functions||(this.functions[a]=[]);this.functions[a].push(b)},
|
||||||
|
onTransportError:function(a,b){this.restartUpdater();this.options.onTransportError(b)},onTimeout:function(){this.restartUpdater();this.options.onTimeout()}};
|
@ -44,6 +44,10 @@
|
|||||||
<arg value="mibew_api:1:common"/>
|
<arg value="mibew_api:1:common"/>
|
||||||
<arg value="--js"/>
|
<arg value="--js"/>
|
||||||
<arg value="mibew_api.js"/>
|
<arg value="mibew_api.js"/>
|
||||||
|
<arg value="--module"/>
|
||||||
|
<arg value="chatserver:1:common"/>
|
||||||
|
<arg value="--js"/>
|
||||||
|
<arg value="chatserver.js"/>
|
||||||
</java>
|
</java>
|
||||||
|
|
||||||
<java jar="${closure.c}" fork="true">
|
<java jar="${closure.c}" fork="true">
|
||||||
|
@ -59,383 +59,6 @@ var FrameUtils = {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
ChatServer = Class.create();
|
|
||||||
/**
|
|
||||||
* @todo Think about error handling
|
|
||||||
*/
|
|
||||||
ChatServer.prototype = {
|
|
||||||
/**
|
|
||||||
* @constructor
|
|
||||||
*/
|
|
||||||
initialize: function(options) {
|
|
||||||
var chatServer = this;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Update timer
|
|
||||||
*/
|
|
||||||
this.updateTimer = null;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Options for the ChatServer object
|
|
||||||
* @private
|
|
||||||
* @todo Check onResponseError handler
|
|
||||||
*/
|
|
||||||
this.options = {
|
|
||||||
// Server gateway URL
|
|
||||||
servl: "",
|
|
||||||
// Frequency for automatic updater
|
|
||||||
requestsFrequency: 2,
|
|
||||||
// Call on request timeout
|
|
||||||
onTimeout: function() {},
|
|
||||||
// Call when transport error was caught
|
|
||||||
onTransportError: function(e) {},
|
|
||||||
// Call when callFunctions related error was caught
|
|
||||||
onCallError: function(e) {},
|
|
||||||
// Call when update related error was caught
|
|
||||||
onUpdateError: function(e) {},
|
|
||||||
// Call when response related error was caught
|
|
||||||
onResponseError: function(e) {}
|
|
||||||
}.extend(options);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Binds request's token and callback function
|
|
||||||
* @type Object
|
|
||||||
* @private
|
|
||||||
*/
|
|
||||||
this.callbacks = {};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Array of periodically called functions
|
|
||||||
* @type Array
|
|
||||||
* @private
|
|
||||||
*/
|
|
||||||
this.callPeriodically = [];
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Options for an Ajax.Request object
|
|
||||||
* @type Array
|
|
||||||
* @private
|
|
||||||
*/
|
|
||||||
this.ajaxOptions = {
|
|
||||||
_method: 'post',
|
|
||||||
asynchronous: true,
|
|
||||||
timeout: 5000,
|
|
||||||
onComplete: chatServer.receiveResponse.bind(chatServer),
|
|
||||||
onException: chatServer.onTransportError.bind(chatServer),
|
|
||||||
onTimeout: chatServer.onTimeout.bind(chatServer)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* An object of the Ajax.Request class
|
|
||||||
* @type Ajax.Request
|
|
||||||
* @private
|
|
||||||
*/
|
|
||||||
this.ajaxRequest = null;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This buffer store requests and responses between sending packages
|
|
||||||
* @private
|
|
||||||
*/
|
|
||||||
this.buffer = [];
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Contains object of registered functions handlers
|
|
||||||
* @private
|
|
||||||
*/
|
|
||||||
this.functions = {}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* An instance of the MibewAPI class
|
|
||||||
* @type MibewAPI
|
|
||||||
* @private
|
|
||||||
*/
|
|
||||||
this.mibewAPI = new MibewAPI(new MibewAPICoreInteraction());
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Make call to the chat server
|
|
||||||
*
|
|
||||||
* @param {Oblect[]} functionsList List of the function objects. See Mibew API
|
|
||||||
* for details.
|
|
||||||
* @param {Function} callbackFunction
|
|
||||||
* @param {Boolean} forceSend Force requests buffer send right after call
|
|
||||||
* @returns {Boolean} boolean true on success and false on failure
|
|
||||||
*/
|
|
||||||
callFunctions: function(functionsList, callbackFunction, forceSend) {
|
|
||||||
try {
|
|
||||||
// Check function objects
|
|
||||||
if (!(functionsList instanceof Array)) {
|
|
||||||
throw new Error("The first arguments must be an array");
|
|
||||||
}
|
|
||||||
for (var i in functionsList) {
|
|
||||||
// Filter 'Prototype' properties
|
|
||||||
if (! functionsList.hasOwnProperty(i)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
this.mibewAPI.checkFunction(functionsList[i], false);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Generate request token
|
|
||||||
var token = this.generateToken();
|
|
||||||
// Store callback function
|
|
||||||
this.callbacks[token] = callbackFunction;
|
|
||||||
|
|
||||||
// Add request to buffer
|
|
||||||
this.buffer.push({
|
|
||||||
'token': token,
|
|
||||||
'functions': functionsList
|
|
||||||
});
|
|
||||||
if (forceSend) {
|
|
||||||
// Force update
|
|
||||||
this.update();
|
|
||||||
}
|
|
||||||
} catch (e) {
|
|
||||||
// Handle errors
|
|
||||||
this.options.onCallError(e);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Call function at every request to build functions list
|
|
||||||
*
|
|
||||||
* @param {Function} functionsListBuilder Call before every request to build a
|
|
||||||
* list of functions that must be called
|
|
||||||
* @param {Function} callbackFunction Call after response received
|
|
||||||
*/
|
|
||||||
callFunctionsPeriodically: function(functionsListBuilder, callbackFunction) {
|
|
||||||
this.callPeriodically.push({
|
|
||||||
functionsListBuilder: functionsListBuilder,
|
|
||||||
callbackFunction: callbackFunction
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Generates unique request token
|
|
||||||
*
|
|
||||||
* @private
|
|
||||||
* @returns {String} Request token
|
|
||||||
*/
|
|
||||||
generateToken: function() {
|
|
||||||
var token;
|
|
||||||
do {
|
|
||||||
// Create token
|
|
||||||
token = "wnd" +
|
|
||||||
(new Date()).getTime().toString() +
|
|
||||||
(Math.round(Math.random() * 50)).toString();
|
|
||||||
// Check token uniqueness
|
|
||||||
} while(token in this.callbacks);
|
|
||||||
return token;
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Process request
|
|
||||||
*
|
|
||||||
* @param {Object} requestObject Request object. See Mibew API for details.
|
|
||||||
* @private
|
|
||||||
*/
|
|
||||||
processRequest: function(requestObject) {
|
|
||||||
var context = new MibewAPIExecutionContext();
|
|
||||||
|
|
||||||
// Get result function
|
|
||||||
var resultFunction = this.mibewAPI.getResultFunction(
|
|
||||||
requestObject.functions,
|
|
||||||
this.callbacks.hasOwnProperty(requestObject.token)
|
|
||||||
);
|
|
||||||
|
|
||||||
if (resultFunction === null) {
|
|
||||||
// Result function not found
|
|
||||||
for (var i in requestObject.functions) {
|
|
||||||
if (! requestObject.functions.hasOwnProperty(i)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
// Execute functions
|
|
||||||
this.processFunction(requestObject.functions[i], context);
|
|
||||||
// Build and store result
|
|
||||||
this.buffer.push(this.mibewAPI.buildResult(
|
|
||||||
context.getResults(),
|
|
||||||
requestObject.token
|
|
||||||
));
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// Result function found
|
|
||||||
if (this.callbacks.hasOwnProperty(requestObject.token)) {
|
|
||||||
// Invoke callback
|
|
||||||
this.callbacks[requestObject.token](resultFunction.arguments);
|
|
||||||
// Remove callback
|
|
||||||
delete this.callbacks[requestObject.token];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Process function
|
|
||||||
*
|
|
||||||
* @param {Object} functionObject Function object. See Mibew API for details
|
|
||||||
* @param {MibewAPIExecutionContext} context Execution context
|
|
||||||
* @private
|
|
||||||
*/
|
|
||||||
processFunction: function(functionObject, context) {
|
|
||||||
if (! this.functions.hasOwnProperty(functionObject["function"])) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// Get function arguments with replaced refences
|
|
||||||
var functionArguments = context.getArgumentsList(functionObject);
|
|
||||||
|
|
||||||
var results = {};
|
|
||||||
for (var i in this.functions[functionObject["function"]]) {
|
|
||||||
if (! this.functions[functionObject["function"]].hasOwnProperty(i)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
// Get results
|
|
||||||
results.extend(this.functions[functionObject["function"]][i](
|
|
||||||
functionArguments
|
|
||||||
));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add function results to the execution context
|
|
||||||
context.storeFunctionResults(functionObject, results);
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Send the request to the chat server
|
|
||||||
*
|
|
||||||
* @param {Object[]} requestsList Array of requests that must be sent to the
|
|
||||||
* chat server
|
|
||||||
* @private
|
|
||||||
*/
|
|
||||||
sendRequests: function(requestsList) {
|
|
||||||
// Create new AJAX request
|
|
||||||
this.ajaxRequest = new Ajax.Request(
|
|
||||||
this.options.servl,
|
|
||||||
this.ajaxOptions.extend({
|
|
||||||
parameters: 'data=' + this.mibewAPI.encodePackage(requestsList)
|
|
||||||
})
|
|
||||||
);
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets up next automatic updater iteration
|
|
||||||
*/
|
|
||||||
runUpdater: function() {
|
|
||||||
if (this.updateTimer == null) {
|
|
||||||
this.update();
|
|
||||||
}
|
|
||||||
this.updateTimer = setTimeout(
|
|
||||||
this.update.bind(this),
|
|
||||||
this.options.requestsFrequency * 1000
|
|
||||||
);
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Restarts the automatic updater
|
|
||||||
*/
|
|
||||||
restartUpdater: function() {
|
|
||||||
// Clear timeout
|
|
||||||
if (this.updateTimer) {
|
|
||||||
clearTimeout(this.updateTimer);
|
|
||||||
}
|
|
||||||
// Clear request onComplete callback
|
|
||||||
if (this.ajaxRequest._options) {
|
|
||||||
this.ajaxRequest._options.onComplete = undefined;
|
|
||||||
}
|
|
||||||
// Update thread
|
|
||||||
this.update();
|
|
||||||
// Restart updater. Try to reconnect after a while
|
|
||||||
this.updateTimer = setTimeout(
|
|
||||||
this.update.bind(this),
|
|
||||||
1000
|
|
||||||
);
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Send request for update thread and client code's requests
|
|
||||||
* @private
|
|
||||||
*/
|
|
||||||
update: function() {
|
|
||||||
if (this.updateTimer) {
|
|
||||||
clearTimeout(this.updateTimer);
|
|
||||||
}
|
|
||||||
for (var i = 0; i < this.callPeriodically.length; i++) {
|
|
||||||
this.callFunctions(
|
|
||||||
this.callPeriodically[i].functionsListBuilder(),
|
|
||||||
this.callPeriodically[i].callbackFunction
|
|
||||||
);
|
|
||||||
}
|
|
||||||
// Check buffer length
|
|
||||||
if (this.buffer.length == 0) {
|
|
||||||
// Rerun updater later
|
|
||||||
this.runUpdater();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
// Send requests
|
|
||||||
this.sendRequests(this.buffer);
|
|
||||||
// Clear requests buffer
|
|
||||||
this.buffer = [];
|
|
||||||
} catch (e) {
|
|
||||||
// Handle errors
|
|
||||||
this.options.onUpdateError(e);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Process response from the Core
|
|
||||||
*
|
|
||||||
* @param {String} responseObject The response object provided by
|
|
||||||
* Ajax.Request class
|
|
||||||
* @private
|
|
||||||
*/
|
|
||||||
receiveResponse: function(responseObject) {
|
|
||||||
// Do not parse empty responses
|
|
||||||
if (responseObject.response == '') {
|
|
||||||
this.runUpdater();
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
var packageObject = this.mibewAPI.decodePackage(responseObject.response);
|
|
||||||
for (var i in packageObject.requests) {
|
|
||||||
this.processRequest(packageObject.requests[i]);
|
|
||||||
}
|
|
||||||
} catch (e) {
|
|
||||||
this.options.onResponseError(e);
|
|
||||||
} finally {
|
|
||||||
this.runUpdater();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Add function that can be called by the Core
|
|
||||||
*
|
|
||||||
* @param {String} functionName Name of the function
|
|
||||||
* @param {Function} handler Provided function
|
|
||||||
*/
|
|
||||||
registerFunction: function(functionName, handler) {
|
|
||||||
if (!(functionName in this.functions)) {
|
|
||||||
this.functions[functionName] = [];
|
|
||||||
}
|
|
||||||
this.functions[functionName].push(handler);
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Call on all AJAX transport errors
|
|
||||||
* @param {Ajax.Request} transport AJAX Transport object
|
|
||||||
* @param {Error} e Error object
|
|
||||||
*/
|
|
||||||
onTransportError: function (transport, e) {
|
|
||||||
this.restartUpdater();
|
|
||||||
this.options.onTransportError(e);
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Call on all timeouts
|
|
||||||
*/
|
|
||||||
onTimeout: function(transport) {
|
|
||||||
this.restartUpdater();
|
|
||||||
this.options.onTimeout()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ChatThreadUpdater = Class.create();
|
ChatThreadUpdater = Class.create();
|
||||||
ChatThreadUpdater.prototype = {
|
ChatThreadUpdater.prototype = {
|
||||||
/**
|
/**
|
||||||
|
387
src/messenger/webim/js/source/chatserver.js
Normal file
387
src/messenger/webim/js/source/chatserver.js
Normal file
@ -0,0 +1,387 @@
|
|||||||
|
/**
|
||||||
|
* @preserve This file is part of Mibew Messenger project.
|
||||||
|
* http://mibew.org
|
||||||
|
*
|
||||||
|
* Copyright (c) 2005-2011 Mibew Messenger Community
|
||||||
|
* License: http://mibew.org/license.php
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class implemets server interaction functionality
|
||||||
|
*/
|
||||||
|
ChatServer = Class.create();
|
||||||
|
/**
|
||||||
|
* @todo Think about error handling
|
||||||
|
*/
|
||||||
|
ChatServer.prototype = {
|
||||||
|
/**
|
||||||
|
* @constructor
|
||||||
|
*/
|
||||||
|
initialize: function(options) {
|
||||||
|
var chatServer = this;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update timer
|
||||||
|
*/
|
||||||
|
this.updateTimer = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Options for the ChatServer object
|
||||||
|
* @private
|
||||||
|
* @todo Check onResponseError handler
|
||||||
|
*/
|
||||||
|
this.options = {
|
||||||
|
// Server gateway URL
|
||||||
|
servl: "",
|
||||||
|
// Frequency for automatic updater
|
||||||
|
requestsFrequency: 2,
|
||||||
|
// Call on request timeout
|
||||||
|
onTimeout: function() {},
|
||||||
|
// Call when transport error was caught
|
||||||
|
onTransportError: function(e) {},
|
||||||
|
// Call when callFunctions related error was caught
|
||||||
|
onCallError: function(e) {},
|
||||||
|
// Call when update related error was caught
|
||||||
|
onUpdateError: function(e) {},
|
||||||
|
// Call when response related error was caught
|
||||||
|
onResponseError: function(e) {}
|
||||||
|
}.extend(options);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Binds request's token and callback function
|
||||||
|
* @type Object
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
this.callbacks = {};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Array of periodically called functions
|
||||||
|
* @type Array
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
this.callPeriodically = [];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Options for an Ajax.Request object
|
||||||
|
* @type Array
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
this.ajaxOptions = {
|
||||||
|
_method: 'post',
|
||||||
|
asynchronous: true,
|
||||||
|
timeout: 5000,
|
||||||
|
onComplete: chatServer.receiveResponse.bind(chatServer),
|
||||||
|
onException: chatServer.onTransportError.bind(chatServer),
|
||||||
|
onTimeout: chatServer.onTimeout.bind(chatServer)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An object of the Ajax.Request class
|
||||||
|
* @type Ajax.Request
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
this.ajaxRequest = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This buffer store requests and responses between sending packages
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
this.buffer = [];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Contains object of registered functions handlers
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
this.functions = {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An instance of the MibewAPI class
|
||||||
|
* @type MibewAPI
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
this.mibewAPI = new MibewAPI(new MibewAPICoreInteraction());
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Make call to the chat server
|
||||||
|
*
|
||||||
|
* @param {Oblect[]} functionsList List of the function objects. See Mibew API
|
||||||
|
* for details.
|
||||||
|
* @param {Function} callbackFunction
|
||||||
|
* @param {Boolean} forceSend Force requests buffer send right after call
|
||||||
|
* @returns {Boolean} boolean true on success and false on failure
|
||||||
|
*/
|
||||||
|
callFunctions: function(functionsList, callbackFunction, forceSend) {
|
||||||
|
try {
|
||||||
|
// Check function objects
|
||||||
|
if (!(functionsList instanceof Array)) {
|
||||||
|
throw new Error("The first arguments must be an array");
|
||||||
|
}
|
||||||
|
for (var i in functionsList) {
|
||||||
|
// Filter 'Prototype' properties
|
||||||
|
if (! functionsList.hasOwnProperty(i)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
this.mibewAPI.checkFunction(functionsList[i], false);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Generate request token
|
||||||
|
var token = this.generateToken();
|
||||||
|
// Store callback function
|
||||||
|
this.callbacks[token] = callbackFunction;
|
||||||
|
|
||||||
|
// Add request to buffer
|
||||||
|
this.buffer.push({
|
||||||
|
'token': token,
|
||||||
|
'functions': functionsList
|
||||||
|
});
|
||||||
|
if (forceSend) {
|
||||||
|
// Force update
|
||||||
|
this.update();
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
// Handle errors
|
||||||
|
this.options.onCallError(e);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Call function at every request to build functions list
|
||||||
|
*
|
||||||
|
* @param {Function} functionsListBuilder Call before every request to build
|
||||||
|
* a list of functions that must be called
|
||||||
|
* @param {Function} callbackFunction Call after response received
|
||||||
|
*/
|
||||||
|
callFunctionsPeriodically: function(functionsListBuilder, callbackFunction) {
|
||||||
|
this.callPeriodically.push({
|
||||||
|
functionsListBuilder: functionsListBuilder,
|
||||||
|
callbackFunction: callbackFunction
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generates unique request token
|
||||||
|
*
|
||||||
|
* @private
|
||||||
|
* @returns {String} Request token
|
||||||
|
*/
|
||||||
|
generateToken: function() {
|
||||||
|
var token;
|
||||||
|
do {
|
||||||
|
// Create token
|
||||||
|
token = "wnd" +
|
||||||
|
(new Date()).getTime().toString() +
|
||||||
|
(Math.round(Math.random() * 50)).toString();
|
||||||
|
// Check token uniqueness
|
||||||
|
} while(token in this.callbacks);
|
||||||
|
return token;
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Process request
|
||||||
|
*
|
||||||
|
* @param {Object} requestObject Request object. See Mibew API for details.
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
processRequest: function(requestObject) {
|
||||||
|
var context = new MibewAPIExecutionContext();
|
||||||
|
|
||||||
|
// Get result function
|
||||||
|
var resultFunction = this.mibewAPI.getResultFunction(
|
||||||
|
requestObject.functions,
|
||||||
|
this.callbacks.hasOwnProperty(requestObject.token)
|
||||||
|
);
|
||||||
|
|
||||||
|
if (resultFunction === null) {
|
||||||
|
// Result function not found
|
||||||
|
for (var i in requestObject.functions) {
|
||||||
|
if (! requestObject.functions.hasOwnProperty(i)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
// Execute functions
|
||||||
|
this.processFunction(requestObject.functions[i], context);
|
||||||
|
// Build and store result
|
||||||
|
this.buffer.push(this.mibewAPI.buildResult(
|
||||||
|
context.getResults(),
|
||||||
|
requestObject.token
|
||||||
|
));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Result function found
|
||||||
|
if (this.callbacks.hasOwnProperty(requestObject.token)) {
|
||||||
|
// Invoke callback
|
||||||
|
this.callbacks[requestObject.token](resultFunction.arguments);
|
||||||
|
// Remove callback
|
||||||
|
delete this.callbacks[requestObject.token];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Process function
|
||||||
|
*
|
||||||
|
* @param {Object} functionObject Function object. See Mibew API for details
|
||||||
|
* @param {MibewAPIExecutionContext} context Execution context
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
processFunction: function(functionObject, context) {
|
||||||
|
if (! this.functions.hasOwnProperty(functionObject["function"])) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// Get function arguments with replaced refences
|
||||||
|
var functionArguments = context.getArgumentsList(functionObject);
|
||||||
|
|
||||||
|
var results = {};
|
||||||
|
for (var i in this.functions[functionObject["function"]]) {
|
||||||
|
if (! this.functions[functionObject["function"]].hasOwnProperty(i)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
// Get results
|
||||||
|
results.extend(this.functions[functionObject["function"]][i](
|
||||||
|
functionArguments
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add function results to the execution context
|
||||||
|
context.storeFunctionResults(functionObject, results);
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Send the request to the chat server
|
||||||
|
*
|
||||||
|
* @param {Object[]} requestsList Array of requests that must be sent to the
|
||||||
|
* chat server
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
sendRequests: function(requestsList) {
|
||||||
|
// Create new AJAX request
|
||||||
|
this.ajaxRequest = new Ajax.Request(
|
||||||
|
this.options.servl,
|
||||||
|
this.ajaxOptions.extend({
|
||||||
|
parameters: 'data=' + this.mibewAPI.encodePackage(requestsList)
|
||||||
|
})
|
||||||
|
);
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets up next automatic updater iteration
|
||||||
|
*/
|
||||||
|
runUpdater: function() {
|
||||||
|
if (this.updateTimer == null) {
|
||||||
|
this.update();
|
||||||
|
}
|
||||||
|
this.updateTimer = setTimeout(
|
||||||
|
this.update.bind(this),
|
||||||
|
this.options.requestsFrequency * 1000
|
||||||
|
);
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Restarts the automatic updater
|
||||||
|
*/
|
||||||
|
restartUpdater: function() {
|
||||||
|
// Clear timeout
|
||||||
|
if (this.updateTimer) {
|
||||||
|
clearTimeout(this.updateTimer);
|
||||||
|
}
|
||||||
|
// Clear request onComplete callback
|
||||||
|
if (this.ajaxRequest._options) {
|
||||||
|
this.ajaxRequest._options.onComplete = undefined;
|
||||||
|
}
|
||||||
|
// Update thread
|
||||||
|
this.update();
|
||||||
|
// Restart updater. Try to reconnect after a while
|
||||||
|
this.updateTimer = setTimeout(
|
||||||
|
this.update.bind(this),
|
||||||
|
1000
|
||||||
|
);
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Send request for update thread and client code's requests
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
update: function() {
|
||||||
|
if (this.updateTimer) {
|
||||||
|
clearTimeout(this.updateTimer);
|
||||||
|
}
|
||||||
|
for (var i = 0; i < this.callPeriodically.length; i++) {
|
||||||
|
this.callFunctions(
|
||||||
|
this.callPeriodically[i].functionsListBuilder(),
|
||||||
|
this.callPeriodically[i].callbackFunction
|
||||||
|
);
|
||||||
|
}
|
||||||
|
// Check buffer length
|
||||||
|
if (this.buffer.length == 0) {
|
||||||
|
// Rerun updater later
|
||||||
|
this.runUpdater();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
// Send requests
|
||||||
|
this.sendRequests(this.buffer);
|
||||||
|
// Clear requests buffer
|
||||||
|
this.buffer = [];
|
||||||
|
} catch (e) {
|
||||||
|
// Handle errors
|
||||||
|
this.options.onUpdateError(e);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Process response from the Core
|
||||||
|
*
|
||||||
|
* @param {String} responseObject The response object provided by
|
||||||
|
* Ajax.Request class
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
receiveResponse: function(responseObject) {
|
||||||
|
// Do not parse empty responses
|
||||||
|
if (responseObject.response == '') {
|
||||||
|
this.runUpdater();
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
var packageObject = this.mibewAPI.decodePackage(responseObject.response);
|
||||||
|
for (var i in packageObject.requests) {
|
||||||
|
this.processRequest(packageObject.requests[i]);
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
this.options.onResponseError(e);
|
||||||
|
} finally {
|
||||||
|
this.runUpdater();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add function that can be called by the Core
|
||||||
|
*
|
||||||
|
* @param {String} functionName Name of the function
|
||||||
|
* @param {Function} handler Provided function
|
||||||
|
*/
|
||||||
|
registerFunction: function(functionName, handler) {
|
||||||
|
if (!(functionName in this.functions)) {
|
||||||
|
this.functions[functionName] = [];
|
||||||
|
}
|
||||||
|
this.functions[functionName].push(handler);
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Call on all AJAX transport errors
|
||||||
|
* @param {Ajax.Request} transport AJAX Transport object
|
||||||
|
* @param {Error} e Error object
|
||||||
|
*/
|
||||||
|
onTransportError: function (transport, e) {
|
||||||
|
this.restartUpdater();
|
||||||
|
this.options.onTransportError(e);
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Call on all timeouts
|
||||||
|
*/
|
||||||
|
onTimeout: function(transport) {
|
||||||
|
this.restartUpdater();
|
||||||
|
this.options.onTimeout()
|
||||||
|
}
|
||||||
|
}
|
@ -38,6 +38,7 @@ var chatParams = {
|
|||||||
}
|
}
|
||||||
//-->
|
//-->
|
||||||
</script>
|
</script>
|
||||||
|
<script type="text/javascript" language="javascript" src="${webimroot}/js/${jsver}/chatserver.js"></script>
|
||||||
<script type="text/javascript" language="javascript" src="${webimroot}/js/${jsver}/chat.js"></script>
|
<script type="text/javascript" language="javascript" src="${webimroot}/js/${jsver}/chat.js"></script>
|
||||||
<style type="text/css">
|
<style type="text/css">
|
||||||
#header{
|
#header{
|
||||||
|
@ -38,6 +38,7 @@ var chatParams = {
|
|||||||
}
|
}
|
||||||
//-->
|
//-->
|
||||||
</script>
|
</script>
|
||||||
|
<script type="text/javascript" language="javascript" src="${webimroot}/js/${jsver}/chatserver.js"></script>
|
||||||
<script type="text/javascript" language="javascript" src="${webimroot}/js/${jsver}/chat.js"></script>
|
<script type="text/javascript" language="javascript" src="${webimroot}/js/${jsver}/chat.js"></script>
|
||||||
<style type="text/css">
|
<style type="text/css">
|
||||||
.tplimage {
|
.tplimage {
|
||||||
|
@ -79,6 +79,7 @@
|
|||||||
window.onresize = setTrueHeight;
|
window.onresize = setTrueHeight;
|
||||||
//-->
|
//-->
|
||||||
</script>
|
</script>
|
||||||
|
<script type="text/javascript" src="${webimroot}/js/${jsver}/chatserver.js"></script>
|
||||||
<script type="text/javascript" src="${webimroot}/js/${jsver}/chat.js"></script>
|
<script type="text/javascript" src="${webimroot}/js/${jsver}/chat.js"></script>
|
||||||
</head>
|
</head>
|
||||||
<body class="body">
|
<body class="body">
|
||||||
|
@ -38,6 +38,7 @@ var chatParams = {
|
|||||||
}
|
}
|
||||||
//-->
|
//-->
|
||||||
</script>
|
</script>
|
||||||
|
<script type="text/javascript" language="javascript" src="${webimroot}/js/${jsver}/chatserver.js"></script>
|
||||||
<script type="text/javascript" language="javascript" src="${webimroot}/js/${jsver}/chat.js"></script>
|
<script type="text/javascript" language="javascript" src="${webimroot}/js/${jsver}/chat.js"></script>
|
||||||
<style type="text/css">
|
<style type="text/css">
|
||||||
.isound { background: url(${tplroot}/images/buttons/sound.gif) no-repeat; width: 19px; height: 19px; }
|
.isound { background: url(${tplroot}/images/buttons/sound.gif) no-repeat; width: 19px; height: 19px; }
|
||||||
|
Loading…
Reference in New Issue
Block a user