?? repubsubio.js
字號:
this.openTunnel = function(){ // We create two iframes here: // one for getting data this.rcvNodeName = "rcvIFrame_"+this.getRandStr(); // set cookie that can be used to find the receiving iframe this.setCookie( [ [this.tunnelFrameKey,this.rcvNodeName], ["path","/"] ], false ); this.rcvNode = dojo.io.createIFrame(this.rcvNodeName); // FIXME: set the src attribute here to the initialization URL dojo.io.setIFrameSrc(this.rcvNode, this.initDoc+"?callback=repubsub.rcvNodeReady&domain="+document.domain); // the other for posting data in reply this.sndNodeName = "sndIFrame_"+this.getRandStr(); this.sndNode = dojo.io.createIFrame(this.sndNodeName); // FIXME: set the src attribute here to the initialization URL dojo.io.setIFrameSrc(this.sndNode, this.initDoc+"?callback=repubsub.sndNodeReady&domain="+document.domain); } this.rcvNodeReady = function(){ // FIXME: why is this sequence number needed? Why isn't the UID gen // function enough? var statusURI = [this.tunnelURI, '/kn_status/', this.getRandStr(), '_', String(this.tunnelInitCount++)].join(""); // (kn._seqNum++); // FIXME: !!!! // this.canRcv = true; this.log("rcvNodeReady"); // FIXME: initialize receiver and request the base topic // dojo.io.setIFrameSrc(this.rcvNode, this.serverBaseURL+"/kn?do_method=blank"); var initURIArr = [ this.serverBaseURL, "/kn?kn_from=", escape(this.tunnelURI), "&kn_id=", escape(this.tunnelID), "&kn_status_from=", escape(statusURI)]; // FIXME: does the above really need a kn_response_flush? won't the // server already know? If not, what good is it anyway? dojo.io.setIFrameSrc(this.rcvNode, initURIArr.join("")); // setup a status path listener, but don't tell the server about it, // since it already knows we're itnerested in our own tunnel status this.subscribe(statusURI, this, "statusListener", true); this.log(initURIArr.join("")); } this.sndNodeReady = function(){ this.canSnd = true; this.log("sndNodeReady"); this.log(this.backlog.length); // FIXME: handle any pent-up send commands if(this.backlog.length > 0){ this.dequeueEvent(); } } this.statusListener = function(evt){ this.log("status listener called"); this.log(evt.status, "info"); } // this handles local event propigation this.dispatch = function(evt){ // figure out what topic it came from if(evt["to"]||evt["kn_routed_from"]){ var rf = evt["to"]||evt["kn_routed_from"]; // split off the base server URL var topic = rf.split(this.serverBaseURL, 2)[1]; if(!topic){ // FIXME: how do we recover when we don't get a sane "from"? Do // we try to route to it anyway? topic = rf; } this.log("[topic] "+topic); if(topic.length>3){ if(topic.slice(0, 3)=="/kn"){ topic = topic.slice(3); } } if(this.attachPathList[topic]){ this.attachPathList[topic](evt); } } } this.subscribe = function( topic /* kn_from in the old terminilogy */, toObj, toFunc, dontTellServer){ if(!this.isInitialized){ this.subscriptionBacklog.push([topic, toObj, toFunc, dontTellServer]); return; } if(!this.attachPathList[topic]){ this.attachPathList[topic] = function(){ return true; } this.log("subscribing to: "+topic); this.topics.push(topic); } var revt = new dojo.io.repubsubEvent(this.tunnelURI, topic, "route"); var rstr = [this.serverBaseURL+"/kn", revt.toGetString()].join(""); dojo.event.kwConnect({ once: true, srcObj: this.attachPathList, srcFunc: topic, adviceObj: toObj, adviceFunc: toFunc }); // NOTE: the above is a local mapping, if we're not the leader, we // should connect our mapping to the topic handler of the peer // leader, this ensures that not matter what happens to the // leader, we don't really loose our heads if/when the leader // goes away. if(!this.rcvNode){ /* this should be an error! */ } if(dontTellServer){ return; } this.log("sending subscription to: "+topic); // create a subscription event object and give it all the props we need // to updates on the specified topic // FIXME: we should only enqueue if this is our first subscription! this.sendTopicSubToServer(topic, rstr); } this.sendTopicSubToServer = function(topic, str){ if(!this.attachPathList[topic]["subscriptions"]){ this.enqueueEventStr(str); this.attachPathList[topic].subscriptions = 0; } this.attachPathList[topic].subscriptions++; } this.unSubscribe = function(topic, toObj, toFunc){ // first, locally disconnect dojo.event.kwDisconnect({ srcObj: this.attachPathList, srcFunc: topic, adviceObj: toObj, adviceFunc: toFunc }); // FIXME: figure out if there are any remaining listeners to the topic, // and if not, inform the server of our desire not to be // notified of updates to the topic } // the "publish" method is really a misnomer, since it really means "take // this event and send it to the server". Note that the "dispatch" method // handles local event promigulation, and therefore we emulate both sides // of a real event router without having to swallow all of the complexity. this.publish = function(topic, event){ var evt = dojo.io.repubsubEvent.initFromProperties(event); // FIXME: need to make sure we have from and to set correctly // before we serialize and send off to the great blue // younder. evt.to = topic; // evt.from = this.tunnelURI; var evtURLParts = []; evtURLParts.push(this.serverBaseURL+"/kn"); // serialize the event to a string and then post it to the correct // topic evtURLParts.push(evt.toGetString()); this.enqueueEventStr(evtURLParts.join("")); } this.enqueueEventStr = function(evtStr){ this.log("enqueueEventStr"); this.backlog.push(evtStr); this.dequeueEvent(); } this.dequeueEvent = function(force){ this.log("dequeueEvent"); if(this.backlog.length <= 0){ return; } if((this.canSnd)||(force)){ dojo.io.setIFrameSrc(this.sndNode, this.backlog.shift()+"&callback=repubsub.sndNodeReady"); this.canSnd = false; }else{ this.log("sndNode not available yet!", "debug"); } }}dojo.io.repubsubEvent = function(to, from, method, id, routeURI, payload, dispname, uid){ this.to = to; this.from = from; this.method = method||"route"; this.id = id||repubsub.getRandStr(); this.uri = routeURI; this.displayname = dispname||repubsub.displayname; this.userid = uid||repubsub.userid; this.payload = payload||""; this.flushChars = 4096; this.initFromProperties = function(evt){ if(evt.constructor = dojo.io.repubsubEvent){ for(var x in evt){ this[x] = evt[x]; } }else{ // we want to copy all the properties of the evt object, and transform // those that are "stock" properties of dojo.io.repubsubEvent. All others should // be copied as-is for(var x in evt){ if(typeof this.forwardPropertiesMap[x] == "string"){ this[this.forwardPropertiesMap[x]] = evt[x]; }else{ this[x] = evt[x]; } } } } this.toGetString = function(noQmark){ var qs = [ ((noQmark) ? "" : "?") ]; for(var x=0; x<this.properties.length; x++){ var tp = this.properties[x]; if(this[tp[0]]){ qs.push(tp[1]+"="+encodeURIComponent(String(this[tp[0]]))); } // FIXME: we need to be able to serialize non-stock properties!!! } return qs.join("&"); }}dojo.io.repubsubEvent.prototype.properties = [["from", "kn_from"], ["to", "kn_to"], ["method", "do_method"], ["id", "kn_id"], ["uri", "kn_uri"], ["displayname", "kn_displayname"], ["userid", "kn_userid"], ["payload", "kn_payload"], ["flushChars", "kn_response_flush"], ["responseFormat", "kn_response_format"] ];// maps properties from their old names to their new names...dojo.io.repubsubEvent.prototype.forwardPropertiesMap = {};// ...and vice versa...dojo.io.repubsubEvent.prototype.reversePropertiesMap = {};// and we then populate them both from the properties listfor(var x=0; x<dojo.io.repubsubEvent.prototype.properties.length; x++){ var tp = dojo.io.repubsubEvent.prototype.properties[x]; dojo.io.repubsubEvent.prototype.reversePropertiesMap[tp[0]] = tp[1]; dojo.io.repubsubEvent.prototype.forwardPropertiesMap[tp[1]] = tp[0];}// static version of initFromProperties, creates new event and object and// returns it after initdojo.io.repubsubEvent.initFromProperties = function(evt){ var eventObj = new dojo.io.repubsubEvent(); eventObj.initFromProperties(evt); return eventObj;}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -