📄 cometd.js
字号:
if(message["id"]){ this.lastId = message.id; } // check to see if we got a /meta channel message that we care about if( (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){ dojo.debug("cometd connection error:", message.error); return; } this.connectionId = message.connectionId; this.connected = true; this.processBacklog(); break; case "/meta/reconnect": if(!message.successful){ dojo.debug("cometd reconnection error:", message.error); return; } this.connected = true; break; case "/meta/subscribe": if(!message.successful){ dojo.debug("cometd subscription error for channel", message.channel, ":", message.error); return; } // this.subscribed(message.channel); dojo.debug(message.channel); break; } } } this.widenDomain = function(domainStr){ // allow us to make reqests to the TLD var cd = domainStr||document.domain; if(cd.indexOf(".")==-1){ return; } // probably file:/// or localhost var dps = cd.split("."); if(dps.length<=2){ return; } // probably file:/// or an RFC 1918 address dps = dps.slice(dps.length-2); document.domain = dps.join("."); return document.domain; } this.postToIframe = function(content, url){ if(!this.phonyForm){ if(dojo.render.html.ie){ this.phonyForm = document.createElement("<form enctype='application/x-www-form-urlencoded' method='POST' style='display: none;'>"); dojo.body().appendChild(this.phonyForm); }else{ this.phonyForm = document.createElement("form"); this.phonyForm.style.display = "none"; // FIXME: will this still work? dojo.body().appendChild(this.phonyForm); this.phonyForm.enctype = "application/x-www-form-urlencoded"; this.phonyForm.method = "POST"; } } this.phonyForm.action = url||cometd.url; this.phonyForm.target = this.rcvNodeName; this.phonyForm.setAttribute("target", this.rcvNodeName); while(this.phonyForm.firstChild){ this.phonyForm.removeChild(this.phonyForm.firstChild); } for(var x in content){ var tn; if(dojo.render.html.ie){ tn = document.createElement("<input type='hidden' name='"+x+"' value='"+content[x]+"'>"); this.phonyForm.appendChild(tn); }else{ tn = document.createElement("input"); this.phonyForm.appendChild(tn); tn.type = "hidden"; tn.name = x; tn.value = content[x]; } } this.phonyForm.submit(); } this.processBacklog = function(){ while(this.backlog.length > 0){ this.sendMessage(this.backlog.shift(), true); } } this.sendMessage = function(message, bypassBacklog){ // FIXME: what about auth fields? if((bypassBacklog)||(this.connected)){ message.connectionId = this.connectionId; message.clientId = cometd.clientId; var bindArgs = { url: cometd.url||djConfig["cometdRoot"], method: "POST", mimetype: "text/json", // FIXME: we should be able to do better than this given that we're sending an array! content: { message: dojo.json.serialize([ message ]) } }; return dojo.io.bind(bindArgs); }else{ this.backlog.push(message); } } this.startup = function(handshakeData){ dojo.debug("startup!"); dojo.debug(dojo.json.serialize(handshakeData)); if(this.connected){ return; } // this.widenDomain(); // NOTE: we require the server to cooperate by hosting // cometdInit.html at the designated endpoint this.rcvNodeName = "cometdRcv_"+cometd._getRandStr(); // the "forever frame" approach var initUrl = cometd.url+"/?tunnelInit=iframe"; // &domain="+document.domain; if(false && dojo.render.html.ie){ // FIXME: DISALBED FOR NOW // use the "htmlfile hack" to prevent the background click junk this.rcvNode = new ActiveXObject("htmlfile"); this.rcvNode.open(); this.rcvNode.write("<html>"); this.rcvNode.write("<script>document.domain = '"+document.domain+"'"); this.rcvNode.write("</html>"); this.rcvNode.close(); var ifrDiv = this.rcvNode.createElement("div"); this.rcvNode.appendChild(ifrDiv); this.rcvNode.parentWindow.dojo = dojo; ifrDiv.innerHTML = "<iframe src='"+initUrl+"'></iframe>" }else{ this.rcvNode = dojo.io.createIFrame(this.rcvNodeName, "", initUrl); // dojo.io.setIFrameSrc(this.rcvNode, initUrl); // we're still waiting on the iframe to call back up to use and // advertise that it's been initialized via tunnelInit } }}cometd.mimeReplaceTransport = new function(){ this.connected = false; this.connectionId = null; this.xhr = null; this.authToken = null; this.lastTimestamp = null; this.lastId = null; this.backlog = []; this.check = function(types, version, xdomain){ return ((!xdomain)&& (dojo.render.html.mozilla)&& // seems only Moz really supports this right now = ( (dojo.lang.inArray(types, "mime-message-block"))); } this.tunnelInit = function(){ if(this.connected){ return; } // FIXME: open up the connection here this.openTunnelWith({ message: dojo.json.serialize([ { channel: "/meta/connect", clientId: cometd.clientId, connectionType: "mime-message-block" // FIXME: auth not passed here! // "authToken": this.authToken } ]) }); this.connected = true; } this.tunnelCollapse = function(){ if(this.connected){ // try to restart the tunnel this.connected = false; this.openTunnelWith({ message: dojo.json.serialize([ { channel: "/meta/reconnect", clientId: cometd.clientId, connectionId: this.connectionId, timestamp: this.lastTimestamp, id: this.lastId // FIXME: no authToken provision! } ]) }); } } this.deliver = cometd.iframeTransport.deliver; // the logic appears to be the same this.handleOnLoad = function(resp){ cometd.deliver(dojo.json.evalJson(this.xhr.responseText)); } this.openTunnelWith = function(content, url){ // set up the XHR object and register the multipart callbacks this.xhr = dojo.hostenv.getXmlhttpObject(); this.xhr.multipart = true; // FIXME: do Opera and Safari support this flag? if(dojo.render.html.mozilla){ this.xhr.addEventListener("load", dojo.lang.hitch(this, "handleOnLoad"), false); }else if(dojo.render.html.safari){ // Blah. WebKit doesn't actually populate responseText and/or responseXML. Useless. dojo.debug("Webkit is broken with multipart responses over XHR = ("); this.xhr.onreadystatechange = dojo.lang.hitch(this, "handleOnLoad"); }else{ this.xhr.onload = dojo.lang.hitch(this, "handleOnLoad"); } this.xhr.open("POST", (url||cometd.url), true); // async post this.xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded"); dojo.debug(dojo.json.serialize(content)); this.xhr.send(dojo.io.argsFromMap(content, "utf8")); } this.processBacklog = function(){ while(this.backlog.length > 0){ this.sendMessage(this.backlog.shift(), true); } } this.sendMessage = function(message, bypassBacklog){ // FIXME: what about auth fields? if((bypassBacklog)||(this.connected)){ message.connectionId = this.connectionId; message.clientId = cometd.clientId; var bindArgs = { url: cometd.url||djConfig["cometdRoot"], method: "POST", mimetype: "text/json", content: { message: dojo.json.serialize([ message ]) } }; return dojo.io.bind(bindArgs); }else{ this.backlog.push(message); } } this.startup = function(handshakeData){ dojo.debugShallow(handshakeData); if(this.connected){ return; } this.tunnelInit(); }}cometd.longPollTransport = new function(){ this.connected = false; this.connectionId = null; this.authToken = null; this.lastTimestamp = null; this.lastId = null; this.backlog = []; this.check = function(types, version, xdomain){ return ((!xdomain)&&(dojo.lang.inArray(types, "long-polling"))); } this.tunnelInit = function(){ if(this.connected){ return; } // FIXME: open up the connection here this.openTunnelWith({ message: dojo.json.serialize([ { channel: "/meta/connect", clientId: cometd.clientId, connectionType: "long-polling" // FIXME: auth not passed here! // "authToken": this.authToken } ]) }); this.connected = true; } this.tunnelCollapse = function(){ if(!this.connected){ // try to restart the tunnel this.connected = false; dojo.debug("clientId:", cometd.clientId); this.openTunnelWith({ message: dojo.json.serialize([ { channel: "/meta/reconnect", connectionType: "long-polling", clientId: cometd.clientId, connectionId: this.connectionId, timestamp: this.lastTimestamp, id: this.lastId // FIXME: no authToken provision! } ]) }); } } this.deliver = cometd.iframeTransport.deliver; // the logic appears to be the same this.openTunnelWith = function(content, url){ dojo.io.bind({ url: (url||cometd.url), method: "post", content: content, mimetype: "text/json", load: dojo.lang.hitch(this, function(type, data, evt, args){ // dojo.debug(evt.responseText); cometd.deliver(data); this.connected = false; this.tunnelCollapse(); }), error: function(){ dojo.debug("tunnel opening failed"); } }); this.connected = true; } this.processBacklog = function(){ while(this.backlog.length > 0){ this.sendMessage(this.backlog.shift(), true); } } this.sendMessage = function(message, bypassBacklog){ // FIXME: what about auth fields? if((bypassBacklog)||(this.connected)){ message.connectionId = this.connectionId; message.clientId = cometd.clientId; var bindArgs = { url: cometd.url||djConfig["cometdRoot"], method: "post", mimetype: "text/json", content: { message: dojo.json.serialize([ message ]) } }; return dojo.io.bind(bindArgs); }else{ this.backlog.push(message); } } this.startup = function(handshakeData){ if(this.connected){ return; } this.tunnelInit(); }}cometd.callbackPollTransport = new function(){ this.connected = false; this.connectionId = null; this.authToken = null; this.lastTimestamp = null; this.lastId = null; this.backlog = []; this.check = function(types, version, xdomain){ // we handle x-domain! return dojo.lang.inArray(types, "callback-polling"); } this.tunnelInit = function(){ if(this.connected){ return; } // FIXME: open up the connection here this.openTunnelWith({ message: dojo.json.serialize([ { channel: "/meta/connect", clientId: cometd.clientId, connectionType: "callback-polling" // FIXME: auth not passed here! // "authToken": this.authToken } ]) }); this.connected = true; } this.tunnelCollapse = function(){ if(!this.connected){ // try to restart the tunnel this.connected = false; this.openTunnelWith({ message: dojo.json.serialize([ { channel: "/meta/reconnect", connectionType: "long-polling", clientId: cometd.clientId, connectionId: this.connectionId, timestamp: this.lastTimestamp, id: this.lastId // FIXME: no authToken provision! } ]) }); } } this.deliver = cometd.iframeTransport.deliver; // the logic appears to be the same this.openTunnelWith = function(content, url){ // create a <script> element to generate the request var req = dojo.io.bind({ url: (url||cometd.url), content: content, mimetype: "text/json", transport: "ScriptSrcTransport", jsonParamName: "jsonp", load: dojo.lang.hitch(this, function(type, data, evt, args){ dojo.debug(dojo.json.serialize(data)); cometd.deliver(data); this.connected = false; this.tunnelCollapse(); }), error: function(){ dojo.debug("tunnel opening failed"); } }); this.connected = true; } this.processBacklog = function(){ while(this.backlog.length > 0){ this.sendMessage(this.backlog.shift(), true); } } this.sendMessage = function(message, bypassBacklog){ // FIXME: what about auth fields? if((bypassBacklog)||(this.connected)){ message.connectionId = this.connectionId; message.clientId = cometd.clientId; var bindArgs = { url: cometd.url||djConfig["cometdRoot"], mimetype: "text/json", transport: "ScriptSrcTransport", jsonParamName: "jsonp", content: { message: dojo.json.serialize([ message ]) } }; return dojo.io.bind(bindArgs); }else{ this.backlog.push(message); } } this.startup = function(handshakeData){ if(this.connected){ return; } this.tunnelInit(); }}cometd.connectionTypes.register("mime-message-block", cometd.mimeReplaceTransport.check, cometd.mimeReplaceTransport);cometd.connectionTypes.register("long-polling", cometd.longPollTransport.check, cometd.longPollTransport);cometd.connectionTypes.register("callback-polling", cometd.callbackPollTransport.check, cometd.callbackPollTransport);cometd.connectionTypes.register("iframe", cometd.iframeTransport.check, cometd.iframeTransport);// FIXME: need to implement fallback-polling, IE XML blockdojo.io.cometd = cometd;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -