RepubsubIO.js
上传用户:kimgenplus
上传日期:2016-06-05
资源大小:20877k
文件大小:10k
源码类别:

OA系统

开发平台:

Java

  1. /*
  2. Copyright (c) 2004-2006, The Dojo Foundation
  3. All Rights Reserved.
  4. Licensed under the Academic Free License version 2.1 or above OR the
  5. modified BSD license. For more information on Dojo licensing, see:
  6. http://dojotoolkit.org/community/licensing.shtml
  7. */
  8. dojo.require("dojo.event.*");
  9. dojo.require("dojo.io.BrowserIO");
  10. dojo.provide("dojo.io.RepubsubIO");
  11. dojo.io.repubsubTranport = new function () {
  12. var rps = dojo.io.repubsub;
  13. this.canHandle = function (kwArgs) {
  14. if ((kwArgs["mimetype"] == "text/javascript") && (kwArgs["method"] == "repubsub")) {
  15. return true;
  16. }
  17. return false;
  18. };
  19. this.bind = function (kwArgs) {
  20. if (!rps.isInitialized) {
  21. rps.init();
  22. }
  23. if (!rps.topics[kwArgs.url]) {
  24. kwArgs.rpsLoad = function (evt) {
  25. kwArgs.load("load", evt);
  26. };
  27. rps.subscribe(kwArgs.url, kwArgs, "rpsLoad");
  28. }
  29. if (kwArgs["content"]) {
  30. var cEvt = dojo.io.repubsubEvent.initFromProperties(kwArgs.content);
  31. rps.publish(kwArgs.url, cEvt);
  32. }
  33. };
  34. dojo.io.transports.addTransport("repubsubTranport");
  35. };
  36. dojo.io.repubsub = new function () {
  37. this.initDoc = "init.html";
  38. this.isInitialized = false;
  39. this.subscriptionBacklog = [];
  40. this.debug = true;
  41. this.rcvNodeName = null;
  42. this.sndNodeName = null;
  43. this.rcvNode = null;
  44. this.sndNode = null;
  45. this.canRcv = false;
  46. this.canSnd = false;
  47. this.canLog = false;
  48. this.sndTimer = null;
  49. this.windowRef = window;
  50. this.backlog = [];
  51. this.tunnelInitCount = 0;
  52. this.tunnelFrameKey = "tunnel_frame";
  53. this.serverBaseURL = location.protocol + "//" + location.host + location.pathname;
  54. this.logBacklog = [];
  55. this.getRandStr = function () {
  56. return Math.random().toString().substring(2, 10);
  57. };
  58. this.userid = "guest";
  59. this.tunnelID = this.getRandStr();
  60. this.attachPathList = [];
  61. this.topics = [];
  62. this.parseGetStr = function () {
  63. var baseUrl = document.location.toString();
  64. var params = baseUrl.split("?", 2);
  65. if (params.length > 1) {
  66. var paramStr = params[1];
  67. var pairs = paramStr.split("&");
  68. var opts = [];
  69. for (var x in pairs) {
  70. var sp = pairs[x].split("=");
  71. try {
  72. opts[sp[0]] = eval(sp[1]);
  73. }
  74. catch (e) {
  75. opts[sp[0]] = sp[1];
  76. }
  77. }
  78. return opts;
  79. } else {
  80. return [];
  81. }
  82. };
  83. var getOpts = this.parseGetStr();
  84. for (var x in getOpts) {
  85. this[x] = getOpts[x];
  86. }
  87. if (!this["tunnelURI"]) {
  88. this.tunnelURI = ["/who/", escape(this.userid), "/s/", this.getRandStr(), "/kn_journal"].join("");
  89. }
  90. if (window["repubsubOpts"] || window["rpsOpts"]) {
  91. var optObj = window["repubsubOpts"] || window["rpsOpts"];
  92. for (var x in optObj) {
  93. this[x] = optObj[x];
  94. }
  95. }
  96. this.tunnelCloseCallback = function () {
  97. dojo.io.setIFrameSrc(this.rcvNode, this.initDoc + "?callback=repubsub.rcvNodeReady&domain=" + document.domain);
  98. };
  99. this.receiveEventFromTunnel = function (evt, srcWindow) {
  100. if (!evt["elements"]) {
  101. this.log("bailing! event received without elements!", "error");
  102. return;
  103. }
  104. var e = {};
  105. for (var i = 0; i < evt.elements.length; i++) {
  106. var ee = evt.elements[i];
  107. e[ee.name || ee.nameU] = (ee.value || ee.valueU);
  108. this.log("[event]: " + (ee.name || ee.nameU) + ": " + e[ee.name || ee.nameU]);
  109. }
  110. this.dispatch(e);
  111. };
  112. this.widenDomain = function (domainStr) {
  113. var cd = domainStr || document.domain;
  114. if (cd.indexOf(".") == -1) {
  115. return;
  116. }
  117. var dps = cd.split(".");
  118. if (dps.length <= 2) {
  119. return;
  120. }
  121. dps = dps.slice(dps.length - 2);
  122. document.domain = dps.join(".");
  123. };
  124. this.parseCookie = function () {
  125. var cs = document.cookie;
  126. var keypairs = cs.split(";");
  127. for (var x = 0; x < keypairs.length; x++) {
  128. keypairs[x] = keypairs[x].split("=");
  129. if (x != keypairs.length - 1) {
  130. cs += ";";
  131. }
  132. }
  133. return keypairs;
  134. };
  135. this.setCookie = function (keypairs, clobber) {
  136. if ((clobber) && (clobber == true)) {
  137. document.cookie = "";
  138. }
  139. var cs = "";
  140. for (var x = 0; x < keypairs.length; x++) {
  141. cs += keypairs[x][0] + "=" + keypairs[x][1];
  142. if (x != keypairs.length - 1) {
  143. cs += ";";
  144. }
  145. }
  146. document.cookie = cs;
  147. };
  148. this.log = function (str, lvl) {
  149. if (!this.debug) {
  150. return;
  151. }
  152. while (this.logBacklog.length > 0) {
  153. if (!this.canLog) {
  154. break;
  155. }
  156. var blo = this.logBacklog.shift();
  157. this.writeLog("[" + blo[0] + "]: " + blo[1], blo[2]);
  158. }
  159. this.writeLog(str, lvl);
  160. };
  161. this.writeLog = function (str, lvl) {
  162. dojo.debug(((new Date()).toLocaleTimeString()) + ": " + str);
  163. };
  164. this.init = function () {
  165. this.widenDomain();
  166. this.openTunnel();
  167. this.isInitialized = true;
  168. while (this.subscriptionBacklog.length) {
  169. this.subscribe.apply(this, this.subscriptionBacklog.shift());
  170. }
  171. };
  172. this.clobber = function () {
  173. if (this.rcvNode) {
  174. this.setCookie([[this.tunnelFrameKey, "closed"], ["path", "/"]], false);
  175. }
  176. };
  177. this.openTunnel = function () {
  178. this.rcvNodeName = "rcvIFrame_" + this.getRandStr();
  179. this.setCookie([[this.tunnelFrameKey, this.rcvNodeName], ["path", "/"]], false);
  180. this.rcvNode = dojo.io.createIFrame(this.rcvNodeName);
  181. dojo.io.setIFrameSrc(this.rcvNode, this.initDoc + "?callback=repubsub.rcvNodeReady&domain=" + document.domain);
  182. this.sndNodeName = "sndIFrame_" + this.getRandStr();
  183. this.sndNode = dojo.io.createIFrame(this.sndNodeName);
  184. dojo.io.setIFrameSrc(this.sndNode, this.initDoc + "?callback=repubsub.sndNodeReady&domain=" + document.domain);
  185. };
  186. this.rcvNodeReady = function () {
  187. var statusURI = [this.tunnelURI, "/kn_status/", this.getRandStr(), "_", String(this.tunnelInitCount++)].join("");
  188. this.log("rcvNodeReady");
  189. var initURIArr = [this.serverBaseURL, "/kn?kn_from=", escape(this.tunnelURI), "&kn_id=", escape(this.tunnelID), "&kn_status_from=", escape(statusURI)];
  190. dojo.io.setIFrameSrc(this.rcvNode, initURIArr.join(""));
  191. this.subscribe(statusURI, this, "statusListener", true);
  192. this.log(initURIArr.join(""));
  193. };
  194. this.sndNodeReady = function () {
  195. this.canSnd = true;
  196. this.log("sndNodeReady");
  197. this.log(this.backlog.length);
  198. if (this.backlog.length > 0) {
  199. this.dequeueEvent();
  200. }
  201. };
  202. this.statusListener = function (evt) {
  203. this.log("status listener called");
  204. this.log(evt.status, "info");
  205. };
  206. this.dispatch = function (evt) {
  207. if (evt["to"] || evt["kn_routed_from"]) {
  208. var rf = evt["to"] || evt["kn_routed_from"];
  209. var topic = rf.split(this.serverBaseURL, 2)[1];
  210. if (!topic) {
  211. topic = rf;
  212. }
  213. this.log("[topic] " + topic);
  214. if (topic.length > 3) {
  215. if (topic.slice(0, 3) == "/kn") {
  216. topic = topic.slice(3);
  217. }
  218. }
  219. if (this.attachPathList[topic]) {
  220. this.attachPathList[topic](evt);
  221. }
  222. }
  223. };
  224. this.subscribe = function (topic, toObj, toFunc, dontTellServer) {
  225. if (!this.isInitialized) {
  226. this.subscriptionBacklog.push([topic, toObj, toFunc, dontTellServer]);
  227. return;
  228. }
  229. if (!this.attachPathList[topic]) {
  230. this.attachPathList[topic] = function () {
  231. return true;
  232. };
  233. this.log("subscribing to: " + topic);
  234. this.topics.push(topic);
  235. }
  236. var revt = new dojo.io.repubsubEvent(this.tunnelURI, topic, "route");
  237. var rstr = [this.serverBaseURL + "/kn", revt.toGetString()].join("");
  238. dojo.event.kwConnect({once:true, srcObj:this.attachPathList, srcFunc:topic, adviceObj:toObj, adviceFunc:toFunc});
  239. if (!this.rcvNode) {
  240. }
  241. if (dontTellServer) {
  242. return;
  243. }
  244. this.log("sending subscription to: " + topic);
  245. this.sendTopicSubToServer(topic, rstr);
  246. };
  247. this.sendTopicSubToServer = function (topic, str) {
  248. if (!this.attachPathList[topic]["subscriptions"]) {
  249. this.enqueueEventStr(str);
  250. this.attachPathList[topic].subscriptions = 0;
  251. }
  252. this.attachPathList[topic].subscriptions++;
  253. };
  254. this.unSubscribe = function (topic, toObj, toFunc) {
  255. dojo.event.kwDisconnect({srcObj:this.attachPathList, srcFunc:topic, adviceObj:toObj, adviceFunc:toFunc});
  256. };
  257. this.publish = function (topic, event) {
  258. var evt = dojo.io.repubsubEvent.initFromProperties(event);
  259. evt.to = topic;
  260. var evtURLParts = [];
  261. evtURLParts.push(this.serverBaseURL + "/kn");
  262. evtURLParts.push(evt.toGetString());
  263. this.enqueueEventStr(evtURLParts.join(""));
  264. };
  265. this.enqueueEventStr = function (evtStr) {
  266. this.log("enqueueEventStr");
  267. this.backlog.push(evtStr);
  268. this.dequeueEvent();
  269. };
  270. this.dequeueEvent = function (force) {
  271. this.log("dequeueEvent");
  272. if (this.backlog.length <= 0) {
  273. return;
  274. }
  275. if ((this.canSnd) || (force)) {
  276. dojo.io.setIFrameSrc(this.sndNode, this.backlog.shift() + "&callback=repubsub.sndNodeReady");
  277. this.canSnd = false;
  278. } else {
  279. this.log("sndNode not available yet!", "debug");
  280. }
  281. };
  282. };
  283. dojo.io.repubsubEvent = function (to, from, method, id, routeURI, payload, dispname, uid) {
  284. this.to = to;
  285. this.from = from;
  286. this.method = method || "route";
  287. this.id = id || repubsub.getRandStr();
  288. this.uri = routeURI;
  289. this.displayname = dispname || repubsub.displayname;
  290. this.userid = uid || repubsub.userid;
  291. this.payload = payload || "";
  292. this.flushChars = 4096;
  293. this.initFromProperties = function (evt) {
  294. if (evt.constructor = dojo.io.repubsubEvent) {
  295. for (var x in evt) {
  296. this[x] = evt[x];
  297. }
  298. } else {
  299. for (var x in evt) {
  300. if (typeof this.forwardPropertiesMap[x] == "string") {
  301. this[this.forwardPropertiesMap[x]] = evt[x];
  302. } else {
  303. this[x] = evt[x];
  304. }
  305. }
  306. }
  307. };
  308. this.toGetString = function (noQmark) {
  309. var qs = [((noQmark) ? "" : "?")];
  310. for (var x = 0; x < this.properties.length; x++) {
  311. var tp = this.properties[x];
  312. if (this[tp[0]]) {
  313. qs.push(tp[1] + "=" + encodeURIComponent(String(this[tp[0]])));
  314. }
  315. }
  316. return qs.join("&");
  317. };
  318. };
  319. 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"]];
  320. dojo.io.repubsubEvent.prototype.forwardPropertiesMap = {};
  321. dojo.io.repubsubEvent.prototype.reversePropertiesMap = {};
  322. for (var x = 0; x < dojo.io.repubsubEvent.prototype.properties.length; x++) {
  323. var tp = dojo.io.repubsubEvent.prototype.properties[x];
  324. dojo.io.repubsubEvent.prototype.reversePropertiesMap[tp[0]] = tp[1];
  325. dojo.io.repubsubEvent.prototype.forwardPropertiesMap[tp[1]] = tp[0];
  326. }
  327. dojo.io.repubsubEvent.initFromProperties = function (evt) {
  328. var eventObj = new dojo.io.repubsubEvent();
  329. eventObj.initFromProperties(evt);
  330. return eventObj;
  331. };