--- googlecode.com/svn/trunk/public_html/meteor.js 2006/11/20 17:59:30 3
+++ googlecode.com/svn/trunk/public_html/meteor.js 2008/02/28 00:21:39 55
@@ -1,279 +1,302 @@
-// Set domain at highest level
-var domainparts = document.domain.split(".");
-document.domain = domainparts[domainparts.length-2]+"."+domainparts[domainparts.length-1];
-
-Function.prototype.bind = function(obj) {
- var method = this,
- temp = function() {
- return method.apply(obj, arguments);
- };
- return temp;
-}
-Function.prototype.andThen=function(g) {
- var f=this;
- var a=this.arguments
- return function(args) {
- f(a);g(args);
- }
-};
-
-function Meteor(instID) {
-
- this.lastmsgreceived = -1;
- this.transferDoc = false;
- this.pingtimer = false;
- this.updatepollfreqtimer = false;
- this.lastrequest = 0;
- this.recvtimes = new Array();
- this.MHostId = false;
- this.callback_process = function() {};
- this.callback_reset = function() {};
- this.callback_eof = function() {};
- this.callback_changemode = function() {};
- this.persist = true;
-
- // Documented public properties
- this.channel = false;
- this.subdomain = "data";
- this.dynamicpageaddress = "push";
- this.backtrack = 0;
- this.smartpoll = true;
- this.pollfreq = 2000;
- this.minpollfreq = 2000;
- this.mode = "stream";
- this.polltimeout=30000;
- this.maxmessages=0;
- this.pingtimeout = 10000;
-
- // Set or retrieve host id. Cookie takes this form:
- // MeteorID=123:6356353/124:098320454;
- var MeteIds = Meteor.readCookie("MeteorID");
- var regex1 = new RegExp("^([0-9\:\/M]+\/)*"+instID+"\:([^\/]+)(\/[0-9\:\/M]+)*$");
- var regex2 = new RegExp("^([0-9\:\/M]+\/)*M\:([^\/]+)(\/[0-9\:\/M]+)*$");
- if (typeof(instID) == "Number" && regex1.exec(MeteIds)) {
- this.MHostId = ma[2];
- } else if (typeof(instID) == "Number") {
- this.MHostId = Math.floor(Math.random()*1000000);
- var newcookie = (MeteIds)?MeteIds+"/":"";
- newcookie += instID+":"+this.MHostId;
- Meteor.createCookie("MeteorID", newcookie);
- } else if (ma = regex2.exec(MeteIds)) {
- this.MHostId = ma[2];
- } else {
- this.MHostId = Math.floor(Math.random()*1000000);
- var newcookie = (MeteIds)?MeteIds+"/":"";
- newcookie += "M:"+this.MHostId;
- Meteor.createCookie("MeteorID", newcookie);
- }
- this.instID = (typeof(instID) != "undefined") ? instID : 0;
-}
-
-Meteor.instances = new Array();
-Meteor.servertimeoffset = 0;
-
-Meteor.create = function(instID) {
- if (!instID) instID = 0;
- Meteor.instances[instID] = new Meteor(instID);
- return Meteor.instances[instID];
-}
-
-Meteor.register = function(ifr) {
- instid = new String(ifr.window.frameElement.id);
- instid = instid.replace("meteorframe_", "");
- ifr.p = this.instances[instid].process.bind(this.instances[instid]);
- ifr.r = this.instances[instid].reset.bind(this.instances[instid]);
- ifr.eof = this.instances[instid].eof.bind(this.instances[instid]);
- ifr.get = this.instances[instid].get.bind(this.instances[instid]);
- ifr.increasepolldelay = this.instances[instid].increasepolldelay.bind(this.instances[instid]);
-}
+/*
+stream: xhrinteractive, iframe, serversent
+longpoll
+smartpoll
+simplepoll
+*/
+
+Meteor = {
+
+ callbacks: {
+ process: function() {},
+ reset: function() {},
+ eof: function() {},
+ statuschanged: function() {},
+ changemode: function() {}
+ },
+ channelcount: 0,
+ channels: {},
+ debugmode: false,
+ frameref: null,
+ host: null,
+ hostid: null,
+ maxpollfreq: 60000,
+ minpollfreq: 2000,
+ mode: "stream",
+ pingtimeout: 20000,
+ pingtimer: null,
+ pollfreq: 3000,
+ port: 80,
+ polltimeout: 30000,
+ recvtimes: [],
+ status: 0,
+ updatepollfreqtimer: null,
+
+ register: function(ifr) {
+ ifr.p = Meteor.process;
+ ifr.r = Meteor.reset;
+ ifr.eof = Meteor.eof;
+ ifr.ch = Meteor.channelInfo;
+ clearTimeout(Meteor.frameloadtimer);
+ Meteor.setstatus(4);
+ Meteor.log("Frame registered");
+ },
+
+ joinChannel: function(channelname, backtrack) {
+ if (typeof(Meteor.channels[channelname]) != "undefined") throw "Cannot join channel "+channelname+": already subscribed";
+ Meteor.channels[channelname] = {backtrack:backtrack, lastmsgreceived:0};
+ Meteor.log("Joined channel "+channelname);
+ Meteor.channelcount++;
+ if (Meteor.status != 0) Meteor.connect();
+ },
+
+ leaveChannel: function(channelname) {
+ if (typeof(Meteor.channels[channelname]) == "undefined") throw "Cannot leave channel "+channelname+": not subscribed";
+ delete Meteor.channels[channelname];
+ Meteor.log("Left channel "+channelname);
+ if (Meteor.status != 0) Meteor.connect();
+ Meteor.channelcount--;
+ },
+
+ connect: function() {
+ Meteor.log("Connecting");
+ if (!Meteor.host) throw "Meteor host not specified";
+ if (isNaN(Meteor.port)) throw "Meteor port not specified";
+ if (!Meteor.channelcount) throw "No channels specified";
+ if (Meteor.status) Meteor.disconnect();
+ Meteor.setstatus(1);
+ var now = new Date();
+ var t = now.getTime();
+ if (!Meteor.hostid) Meteor.hostid = t+""+Math.floor(Math.random()*1000000)
+ document.domain = Meteor.extract_xss_domain(document.domain);
+ if (Meteor.mode=="stream") Meteor.mode = Meteor.selectStreamTransport();
+ Meteor.log("Selected "+Meteor.mode+" transport");
+ if (Meteor.mode=="xhrinteractive" || Meteor.mode=="iframe" || Meteor.mode=="serversent") {
+ if (Meteor.mode == "iframe") {
+ Meteor.loadFrame(Meteor.getSubsUrl());
+ } else {
+ Meteor.loadFrame("http://"+Meteor.host+((Meteor.port==80)?"":":"+Meteor.port)+"/stream.html");
+ }
+ clearTimeout(Meteor.pingtimer);
+ Meteor.pingtimer = setTimeout(Meteor.pollmode, Meteor.pingtimeout);
-Meteor.setServerTime = function(timestamp) {
- var now = new Date();
- var clienttime = (now.getTime() / 1000);
- Meteor.servertimeoffset = timestamp - clienttime;
-}
+ } else {
+ Meteor.loadFrame("http://"+Meteor.host+((Meteor.port==80)?"":":"+Meteor.port)+"/poll.html");
+ Meteor.recvtimes[0] = t;
+ if (Meteor.updatepollfreqtimer) clearTimeout(Meteor.updatepollfreqtimer);
+ if (Meteor.mode=='smartpoll') Meteor.updatepollfreqtimer = setInterval(Meteor.updatepollfreq, 2500);
+ if (Meteor.mode=='longpoll') Meteor.pollfreq = Meteor.minpollfreq;
+ }
+ Meteor.lastrequest = t;
+ },
-Meteor.prototype.start = function() {
- this.persist = (this.maxmessages)?1:0;
- this.smartpoll = (this.smartpoll)?1:0;
- this.mode = (this.mode=="stream")?"stream":"poll";
- if (!this.subdomain || !this.channel) throw "Channel or Meteor subdomain host not specified";
- var now = new Date();
- var t = now.getTime();
- if (typeof(this.transferDoc)=="object") {
- this.transferDoc.open();
- this.transferDoc.close();
- delete this.transferDoc;
- }
- if (document.getElementById("meteorframe_"+this.instID)) {
- document.body.removeChild(document.getElementById("meteorframe_"+this.instID));
- }
- if (this.mode=="stream") {
- if (document.all) {
- this.transferDoc = new ActiveXObject("htmlfile");
- this.transferDoc.open();
- this.transferDoc.write("");
- this.transferDoc.write("