⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cometda.js

📁 包括电子政务系统的架构设计、工作流引擎的设计与开发、工作流图形定义工具的设计与开发等
💻 JS
📖 第 1 页 / 共 2 页
字号:
//AdapterRegistry.js
dojo.AdapterRegistry = function(/*Boolean?*/ returnWrappers){
	this.pairs = [];
	this.returnWrappers = returnWrappers || false;
};
dojo.extend(dojo.AdapterRegistry, {
	register: function(/*String*/ name, /*Function*/ check, /*Function*/ wrap, /*Boolean?*/ directReturn, /*Boolean?*/ override){
		this.pairs[((override) ? "unshift" : "push")]([name, check, wrap, directReturn]);
	},
	match: function(/* ... */){
		for(var i = 0; i < this.pairs.length; i++){
			var pair = this.pairs[i];
			if(pair[1].apply(this, arguments)){
				if((pair[3])||(this.returnWrappers)){
					return pair[2];
				}else{
					return pair[2].apply(this, arguments);
				}
			}
		}
		throw new Error("No match found");
	},
	unregister: function(name){
		for(var i = 0; i < this.pairs.length; i++){
			var pair = this.pairs[i];
			if(pair[0] == name){
				this.pairs.splice(i, 1);
				return true;
			}
		}
		return false;
	}
});

//_base.js
dojox.cometd = {
	Connection: function(prefix){
		dojo.mixin(this, {
		 	"DISCONNECTED": "DISCONNECTED",		// _initialized==false 	&& _connected==false
		 	"CONNECTING": "CONNECTING",			// _initialized==true	&& _connected==false (handshake sent)
		 	"CONNECTED": "CONNECTED",			// _initialized==true	&& _connected==true (first successful connect)
		 	"DISCONNECTING": "DISCONNECING",	// _initialized==false 	&& _connected==true (disconnect sent)
	        
	        prefix: prefix,
			_initialized: false,
			_connected: false,
			_polling: false,
			_handshook: false,
	        
			expectedNetworkDelay: 10000, // expected max network delay
			connectTimeout: 0,	     // If set, used as ms to wait for a connect response and sent as the advised timeout
	        
			version:	"1.0",
			minimumVersion: "0.9",
			clientId: null,
			messageId: 0,
			batch: 0,
	        
			_isXD: false,
			handshakeReturn: null,
			currentTransport: null,
			url: null,
			lastMessage: null,
			_messageQ: [],
			handleAs: "json",
			_advice: {},
			_backoffInterval: 0,
			_backoffIncrement: 1000,
			_backoffMax: 60000,
			_deferredSubscribes: {},
			_deferredUnsubscribes: {},
			_subscriptions: [],
			_extendInList: [],	// List of functions invoked before delivering messages
			_extendOutList: []	// List of functions invoked before sending messages
			
		});
		this.state = function() {
			return this._initialized ? 
				(this._connected ? "CONNECTED" : "CONNECTING") : 
				(this._connected ? "DISCONNECTING" : "DISCONNECTED");
		};
		this.init = function(	/*String*/	root,
					/*Object?*/ props,
					/*Object?*/ bargs){	// return: dojo.Deferred
			
			// try to select an XD-capable transport
			props = props || {};
			// go ask the short bus server what we can support
			props.version = this.version;
			props.minimumVersion = this.minimumVersion;
			props.channel = "/meta/handshake";
			props.id = "" + this.messageId++;
	
			this.url = root || dojo.config["cometdRoot"];
			if(!this.url){
				throw "no cometd root";
				return null;
			}
			var regexp = "^(([^:/?#]+):)?(//([^/?#]*))?([^?#]*)(\\?([^#]*))?(#(.*))?$";
			var parts = ("" + window.location).match(new RegExp(regexp));
			if(parts[4]){
				var tmp = parts[4].split(":");
				var thisHost = tmp[0];
				var thisPort = tmp[1]||"80"; // FIXME: match 443
	
				parts = this.url.match(new RegExp(regexp));
				if(parts[4]){
					tmp = parts[4].split(":");
					var urlHost = tmp[0];
					var urlPort = tmp[1]||"80";
					this._isXD = ((urlHost != thisHost)||(urlPort != thisPort));
				}
			}
	
			if(!this._isXD){
				props.supportedConnectionTypes = dojo.map(dojox.cometd.connectionTypes.pairs, "return item[0]");
			}
	
			props = this._extendOut(props);
	
			var bindArgs = {
				url: this.url,
				handleAs: this.handleAs,
				content: { "message": dojo.toJson([props]) },
				load: dojo.hitch(this,function(msg){
					this._backon();
					this._finishInit(msg);
				}),
				error: dojo.hitch(this,function(e){
					this._backoff();
					this._finishInit([{}]);
				}),
				timeout: this.expectedNetworkDelay
			};
	
			if(bargs){
				dojo.mixin(bindArgs, bargs);
			}
			this._props = props;
			for(var tname in this._subscriptions){
				for(var sub in this._subscriptions[tname]){
					if(this._subscriptions[tname][sub].topic){
			 			dojo.unsubscribe(this._subscriptions[tname][sub].topic);
					}
				}
			}
			this._messageQ = [];
			this._subscriptions = [];
			this._initialized = true;
			this.batch = 0;
			this.startBatch();
			
			var r;
			// if xdomain, then we assume jsonp for handshake
			if(this._isXD){
				bindArgs.callbackParamName = "jsonp";
				r = dojo.io.script.get(bindArgs);
			}else{
				r = dojo.xhrPost(bindArgs);
			}
			return r;
		};
		this.publish = function(/*String*/ channel, /*Object*/ data, /*Object?*/ props){
			var message = {
				data: data,
				channel: channel
			};
			if(props){
				dojo.mixin(message, props);
			}
			this._sendMessage(message);
		};
		this.subscribe = function(	/*String */	channel,
						/*Object */	objOrFunc,
						/*String */	funcName,
						/*Object?*/ props){ // return: dojo.Deferred
	
			props = props||{};
			if(objOrFunc){
				var tname = prefix + channel;
				var subs = this._subscriptions[tname];
				if(!subs || subs.length == 0){
					subs = [];
					props.channel = "/meta/subscribe";
					props.subscription = channel;
					this._sendMessage(props);
					
					var _ds = this._deferredSubscribes;
					if(_ds[channel]){
						_ds[channel].cancel();
						delete _ds[channel];
					}
					_ds[channel] = new dojo.Deferred();
				}
				
				for(var i in subs){
					if(subs[i].objOrFunc === objOrFunc && (!subs[i].funcName&&!funcName||subs[i].funcName==funcName) ){
						return null;
					}
				}
				
				var topic = dojo.subscribe(tname, objOrFunc, funcName);
				subs.push({ 
					topic: topic, 
					objOrFunc: objOrFunc, 
					funcName: funcName
				});
				this._subscriptions[tname] = subs;
			}
			var ret = this._deferredSubscribes[channel] || {};
			ret.args = dojo._toArray(arguments);
			return ret; // dojo.Deferred
		};
		this.unsubscribe = function(	/*String*/	channel,
						/*Object?*/ objOrFunc,
						/*String?*/ funcName,
						/*Object?*/ props){
	
			if(
				(arguments.length == 1) &&
				(!dojo.isString(channel)) &&
				(channel.args)
			){
				// it's a subscription handle, unroll
				return this.unsubscribe.apply(this, channel.args);
			}
			
			var tname = prefix + channel;
			var subs = this._subscriptions[tname];
			if(!subs || subs.length==0){
				return null;
			}
	
			var s=0;
			for(var i in subs){
				var sb = subs[i];
				if((!objOrFunc) ||
					(
						sb.objOrFunc===objOrFunc &&
						(!sb.funcName && !funcName || sb.funcName==funcName)
					)
				){
					dojo.unsubscribe(subs[i].topic);
					delete subs[i];
				}else{
					s++;
				}
			}
			
			if(s == 0){
				props = props || {};
				props.channel = "/meta/unsubscribe";
				props.subscription = channel;
				delete this._subscriptions[tname];
				this._sendMessage(props);
				this._deferredUnsubscribes[channel] = new dojo.Deferred();
				if(this._deferredSubscribes[channel]){
					this._deferredSubscribes[channel].cancel();
					delete this._deferredSubscribes[channel];
				}
			}
			return this._deferredUnsubscribes[channel]; // dojo.Deferred
		};
		this.disconnect = function(){
	
			for(var tname in this._subscriptions){
				for(var sub in this._subscriptions[tname]){
					if(this._subscriptions[tname][sub].topic){
						dojo.unsubscribe(this._subscriptions[tname][sub].topic);
					}
				}
			}
			this._subscriptions = [];
			this._messageQ = [];
			if(this._initialized && this.currentTransport){
				this._initialized=false;
				this.currentTransport.disconnect();
			}
			if(!this._polling) {
				this._connected=false;
				this._publishMeta("connect",false);
			}
			this._initialized=false;
			this._handshook=false;
			this._publishMeta("disconnect",true);
		};
		this.subscribed = function(	/*String*/channel, /*Object*/message){ }
		this.unsubscribed = function(/*String*/channel, /*Object*/message){ }
		
		// private methods (TODO name all with leading _)
	
		this.tunnelInit = function(childLocation, childDomain){
			
		};
		this.tunnelCollapse = function(){
			
		};
		this._backoff = function(){
			if(!this._advice){
				this._advice={reconnect:"retry",interval:0};
			}else if(!this._advice.interval){
				this._advice.interval = 0;
			}
			
			if(this._backoffInterval < this._backoffMax){
				this._backoffInterval += this._backoffIncrement;
			}
		}
		
		this._backon = function(){
			this._backoffInterval=0;
		}
	
		this._interval = function(){
			var i = this._backoffInterval + (this._advice ? (this._advice.interval ? this._advice.interval : 0) : 0);
			if (i>0){
				
			}
			return i;
		}
		
		this._publishMeta = function(action,successful,props){
			try {
				var meta = {cometd:this,action:action,successful:successful,state:this.state()};
				if (props){
					dojo.mixin(meta, props);
				}
				dojo.publish(this.prefix + "/meta", [meta]);
			} catch(e) {
				
			}
		}
	
		this._finishInit = function(data){
			//	summary:
			//		Handle the handshake return from the server and initialize
			//		connection if all is OK
			data = data[0];
			this.handshakeReturn = data;
			// remember any advice
			if(data["advice"]){
				this._advice = data.advice;
			}
	
			var successful = data.successful ? data.successful : false;
			
			// check version
			if(data.version < this.minimumVersion){
				if (console.log)
				    
				successful=false;
				this._advice.reconnect="none";
			}
			if(successful){
				this.currentTransport = dojox.cometd.connectionTypes.match(
					data.supportedConnectionTypes,
					data.version,
					this._isXD
				);
				var transport = this.currentTransport;
				// initialize the transport
				transport._cometd = this;
				transport.version = data.version;
				this.clientId = data.clientId;
				this.tunnelInit = transport.tunnelInit && dojo.hitch(transport, "tunnelInit");
				this.tunnelCollapse = transport.tunnelCollapse && dojo.hitch(transport, "tunnelCollapse");
				transport.startup(data);
			}
	
			this._publishMeta("handshake",successful,{reestablish: successful && this._handshook});
			if(successful){
				this._handshook=true;
			}else{
				// If there is a problem
				
				// follow advice
				if(!this._advice || this._advice["reconnect"] != "none"){
					setTimeout(dojo.hitch(this, "init", this.url, this._props), this._interval());
				}
			}
		}
	
		// FIXME: lots of repeated code...why?
		this._extendIn = function(message){
			// summary: Handle extensions for inbound messages
			dojo.forEach(dojox.cometd._extendInList, function(f){
				message = f(message) || message;
			});
			return message;
		}
	
		this._extendOut = function(message){
			// summary: Handle extensions for inbound messages
			dojo.forEach(dojox.cometd._extendOutList, function(f){
				message = f(message) || message;
			});
			return message;
		}
	
		this.deliver = function(messages){
			dojo.forEach(messages, this._deliver, this);
			return messages;
		}
	
		this._deliver = function(message){
			// dipatch events along the specified path
			
			message = this._extendIn(message);
	
			if(!message["channel"]){
				if(message["success"] !== true){
					return;
				}
			}
			this.lastMessage = message;
	
			if(message.advice){
				this._advice = message.advice; // TODO maybe merge?
			}
	
			// check to see if we got a /meta channel message that we care about
			var deferred=null;
			if(	(message["channel"]) &&
				(message.channel.length > 5) &&
				(message.channel.substr(0, 5) == "/meta")){
				// check for various meta topic actions that we need to respond to
				switch(message.channel){
					case "/meta/connect":
						if(message.successful && !this._connected){
							this._connected = this._initialized;
							this.endBatch();
						}else if(!this._initialized){
							this._connected = false; // finish disconnect
						}
						if(this._initialized){
							this._publishMeta("connect",message.successful);
						}
						break;
					case "/meta/subscribe":
						deferred = this._deferredSubscribes[message.subscription];
						try
						{
							if(!message.successful){
								if(deferred){
									deferred.errback(new Error(message.error));
									deferred.callback();
								}
								this.currentTransport.cancelConnect();

								return;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -