d671d8f52e8c2f88a252c8db15502231cb73dadc
[xynt.git] / web / xynt / xynt-http-streaming.js
1 function globst() {
2     this.st = -1;
3     this.st_loc = -1;
4     this.st_loc_new = -1;
5     this.comms  = new Array;
6 }
7
8 globst.prototype = {
9     st: -1,
10     st_loc: -1,
11     st_loc_new: -1,
12     comms: null,
13     sleep_hd: null,
14
15     sleep: function(delay) {
16         st.st_loc_new++;
17
18         this.sleep_hdl = setTimeout(function(obj){ if (obj.st_loc_new > obj.st_loc) { obj.st_loc++; obj.sleep_hdl = null; }},
19                                    delay, this);
20     },
21
22     abort: function() {
23         if (this.sleep_hdl != null) {
24             clearTimeout(this.sleep_hdl);
25             this.sleep_hdl = null;
26         }
27     }
28 }
29
30 function http_streaming(win, cons)
31 {
32     this.console = cons;
33     this.win = win;
34     this.doc = win.document;
35     this.keepalive_old = -1;
36     this.keepalive_new = -1;
37     this.gst = new globst();
38     this.cmdproc = function(com){eval(com);}
39 }
40
41 http_streaming.prototype = {
42     console:           null,
43     win:               null,
44     doc:               null,
45     ifra:              null,
46     page:              null,
47     watchdog_hdl:      null,
48     keepalive_old:    -1,
49     keepalive_new:    -1,
50     keepalives_equal:  0,
51     keepalives_eq_max: 6,
52     watchdog_timeout:  100,
53     watchdog_ct:       0,
54     watchdog_checktm:  20,
55     watchable:         false,
56     gst:               null,
57     restart_n:         0,
58     cmdproc:           null,
59     comm_match:        /_*@BEGIN@(.*?)@END@/g, 
60     comm_clean:        /_*@BEGIN@(.*?)@END@/,
61     ctx_old:           "",
62     ctx_old_len:       0,
63     // ctx_new:           "",
64     ctx_new_len:       0,
65     stream:            "",
66
67     start: function(page) {
68         this.log("http_streaming:start restart: "+this.restart_n);
69         this.keepalives_equal = 0;
70         this.ifra = this.doc.createElement("iframe");
71         this.ifra.style.visibility = "hidden";
72         this.doc.body.appendChild(this.ifra);
73         if (page != null)
74             this.page = page;
75         // this.log(this.ifra);
76         this.ifra.contentWindow.location.href = this.page;
77         this.watchdog_ct  = 0;
78         this.watchdog_hdl = setTimeout(function(obj) { obj.log("tout1"); obj.watchdog(); }, this.watchdog_timeout, this);
79     },
80
81     watchdog: function () {
82         var i, again;
83         var comm_newpart, comm_len, comm_arr;
84
85         // WATCHDOGING THE CONNECTION
86         if ( (this.watchdog_ct % this.watchdog_checktm) == 0 || !this.watchable) {
87             this.log("hs::watchdog: start, cur equal times: "+this.keepalives_equal);
88             if (!this.watchable) {
89                 do {
90                     if (typeof(this.ifra.contentWindow.http_streaming) == 'undefined')
91                         break;
92                     /*
93                       on IE7 the the window frame scope is cleaned after the href is set, so we wait 
94                       for a well know variable value before assign this object value to it (OO is a passion)
95                     */
96                     if (this.ifra.contentWindow.http_streaming == "ready") {
97                         this.ifra.contentWindow.http_streaming = this;
98                         this.watchable = true;
99                         this.log("hs::watchdog: watchable = yes");
100                     }
101                 } while (false);
102             }
103             this.log("hs::watchdog: this.keepalive_old: "+this.keepalive_old+" this.keepalive_new: "+this.keepalive_new);
104             if (this.keepalive_old == this.keepalive_new) {
105                 this.keepalives_equal++;
106             }
107             else {
108                 this.keepalive_old = this.keepalive_new;
109                 this.keepalives_equal = 0;
110             }
111             
112             if (this.keepalives_equal > this.keepalives_eq_max) {
113                 this.log("hs::watchdog: MAX ACHIEVED "+this.keepalives_equal);
114                 this.reload();
115                 return;
116             }
117         }
118
119         // PICK COMMANDS FROM STREAM
120         do {
121             // CHECK: maybe again here isn't needed 
122             again = 0;
123             if (typeof(this.ifra.contentWindow.ctx_new) == 'undefined')
124                 break;
125             if (this.ifra.contentWindow.ctx_new.length == this.ctx_old_len) {
126                 // this.ctx_new = this.ctx_old = "";
127                 // FIXME find a more robust clean method
128                 break;
129             }
130             this.log("new: "+ this.ifra.contentWindow.ctx_new.length + "  old: "+this.ctx_old_len);
131             this.keepalive_new++;            
132             for (i = this.ctx_old_len ; i < this.ifra.contentWindow.ctx_new.length ; i++) {
133                 if (this.ifra.contentWindow.ctx_new[i] != '_') 
134                     break;
135             }
136             if (i == this.ifra.contentWindow.ctx_new.length) {
137                 this.ctx_old_len = i;
138                 break;
139             }
140             comm_newpart = this.ifra.contentWindow.ctx_new.substr(this.ctx_old_len);    
141             comm_len = 0;
142             comm_arr = comm_newpart.match(this.comm_match);
143
144             if (comm_arr) {
145                 for (i = 0 ; i < comm_arr.length ; i++) {
146                     var temp = comm_arr[i].replace(this.comm_clean,"$1").split("|");
147
148                     this.gst.comms = this.gst.comms.concat(temp);
149                     // XX alert("COMM_ARR["+i+"]: "+comm_arr[i]+"  LEN:"+comm_arr[i].length);
150                     comm_len += comm_arr[i].length;
151                 }
152                 this.ctx_old += comm_newpart.substr(0,comm_len);
153                 again = 1;
154             }
155             this.ctx_old_len = this.ctx_old.length;
156         } while (again);
157         
158
159
160         // EXECUTION OF STREAM COMMANDS
161         do {
162             again = 0;
163             //MOP ?? xhrrestart = 0;
164             if (this.gst.st_loc < this.gst.st_loc_new) {
165                 // there is some slow actions running
166                 break;
167             }
168             else if (this.gst.comms.length > 0) {
169                 var singlecomm;
170                 
171                 singlecomm = this.gst.comms.shift();
172                 // alert("EXE"+gugu);
173                 // $("xhrdeltalog").innerHTML = "EVALL: "+singlecomm.replace("<", "&lt;", "g"); +"<br>";
174                 //xx this.hbit("+");
175                 
176                 this.cmdproc(singlecomm);
177                 again = 1;
178             }
179         } while (again);
180
181
182         this.watchdog_ct++;
183         this.watchdog_hdl = setTimeout(function(obj) { /* obj.log("tout2"); */ obj.watchdog(); }, this.watchdog_timeout, this);
184         return;
185     },
186     
187     keepalive: function (s) {
188         this.log("hs::keepalive");
189         if (s != null) {
190             this.log(s);
191             this.ifra.contentWindow.ctx_new += "@BEGIN@"+s+"@END@";
192         }
193         else {
194             this.ifra.contentWindow.ctx_new += "_";
195         }
196         // this.keepalive_new++;
197     },
198
199     abort: function () {
200         this.gst.abort();
201         if (this.watchdog_hdl != null) {
202             clearTimeout(this.watchdog_hdl);
203             this.watchdog_hdl = null;
204         }
205
206         this.restart_n++;
207         this.log("hs::reload");
208         this.watchable = false;
209         if (this.ifra != null) {
210             this.doc.body.removeChild(this.ifra);
211             delete this.ifra;
212             this.ifra = null;
213         }
214         this.ctx_old = "";
215         this.ctx_old_len = 0;
216     },
217
218     reload: function () {
219         this.abort();
220         this.start(null);
221     },
222
223     log: function (s) {
224         if (this.console != null) {
225             return (this.console.log(s));
226         }
227     }
228 }