--- googlecode.com/svn/trunk/public_html/meteor.js 2006/11/23 15:53:25 7 +++ googlecode.com/svn/trunk/public_html/meteor.js 2007/10/10 22:24:32 30 @@ -19,79 +19,61 @@ function Meteor(instID) { - this.lastmsgreceived = -1; this.transferDoc = false; this.pingtimer = false; this.updatepollfreqtimer = false; this.lastrequest = 0; - this.recvtimes = new Array(); + this.recvtimes = []; this.MHostId = false; this.callback_process = function() {}; this.callback_reset = function() {}; this.callback_eof = function() {}; this.callback_changemode = function() {}; this.callback_statuschanged = function() {}; - this.persist = true; + this.persist = 1; this.frameloadtimer = false; - this.frameurl = false; + this.debugmode = false; + this.subsurl = false; + this.channels = {}; + this.channelcount = 0; + this.streamreq = false; + this.byteoffset = 0; // Documented public properties - this.channel = false; this.subdomain = "data"; this.dynamicpageaddress = "push"; - this.backtrack = 0; - this.smartpoll = true; + this.smartpoll = 1; this.pollfreq = 2000; this.minpollfreq = 2000; this.mode = "stream"; - this.polltimeout=30000; - this.maxmessages=0; + this.polltimeout = 30000; this.pingtimeout = 10000; + this.maxmessages = 0; this.status = 0; /* Statuses: 0 = Uninitialised, 1 = Loading stream, 2 = Loading controller frame, - 3 = Controller frame timeout, retrying every 5 seconds + 3 = Controller frame timeout, retrying. 4 = Controller frame loaded and ready 5 = Receiving data */ - // 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; + this.MHostId = Math.floor(Math.random()*100000000)+""+this.instID; } Meteor.instances = new Array(); -Meteor.servertimeoffset = 0; Meteor.create = function(instID) { - if (!instID) instID = 0; + if (!instID) instID = Meteor.instances.length; 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_", ""); + instid = instid.replace(/.*_([0-9]*)$/, "$1"); 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]); @@ -99,112 +81,165 @@ ifr.increasepolldelay = this.instances[instid].increasepolldelay.bind(this.instances[instid]); clearTimeout(this.instances[instid].frameloadtimer); this.instances[instid].setstatus(4); + if (this.debugmode) console.log("Frame registered"); } -Meteor.setServerTime = function(timestamp) { - var now = new Date(); - var clienttime = (now.getTime() / 1000); - Meteor.servertimeoffset = timestamp - clienttime; +Meteor.reset = function(ifr) { + instid = new String(ifr.window.frameElement.id); + instid = instid.replace(/.*_([0-9]*)$/, "$1"); + this.instances[instid].reset(); +} + +window.onunload = function() { + for (var i in Meteor.instances) { + if (Meteor.instances[i].transferDoc) delete Meteor.instances[i].transferDoc; + } +} + + +Meteor.prototype.joinChannel = function(channelname, backtrack) { + if (typeof(this.channels[channelname]) != "undefined") throw "Cannot join channel "+channelname+": already subscribed"; + this.channels[channelname] = {backtrack:backtrack, lastmsgreceived:0}; + if (this.debugmode) console.log("Joined channel "+channelname+", channel list follows"); + if (this.debugmode) console.log(this.channels); + if (this.status != 0) this.start(); + this.channelcount++; +} + +Meteor.prototype.leaveChannel = function(channelname) { + if (typeof(this.channels[channelname]) == "undefined") throw "Cannot leave channel "+channelname+": not subscribed"; + delete this.channels[channelname]; + if (this.status != 0) this.start(); + this.channelcount--; } Meteor.prototype.start = function() { - this.persist = (this.maxmessages)?1:0; + this.persist = (this.persist)?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"; + if (!this.subdomain || !this.channelcount) throw "Channel or Meteor subdomain host not specified"; + this.stop(); 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)); - } + this.setstatus(1); + this.updateSubsUrl(); if (this.mode=="stream") { if (document.all) { - this.setstatus(1); - this.transferDoc = new ActiveXObject("htmlfile"); - this.transferDoc.open(); - this.transferDoc.write(""); - this.transferDoc.write("