add WebSocket to transports bouquet
[brisk.git] / web / xynt-streaming.js
1 // old targetpage == page and moved into start method
2
3 //
4 // CLASS transport_ws
5 //
6 function transport_ws(doc, xynt_streaming, page)
7 {
8     this.ctx_new = "";
9     var self = this;
10
11     this.doc = doc;
12     this.failed = false;
13     this.xynt_streaming = xynt_streaming;
14     try {
15         this.ws = new WebSocket(page);
16         this.ws.onopen = function () {
17             self.xynt_streaming.log("onopen");
18             if (this.readyState == 1) {
19                 // connected
20                 self.ws_cb("open");
21             }
22         };
23         this.ws.onmessage = function (msg) {
24             self.xynt_streaming.log("onmessage");
25             // new data in msg.data
26             self.ctx_new += msg.data;
27         };
28         this.ws.onclose = function (msg) {
29             self.xynt_streaming.log("onclose");
30             self.ws_cb("close");
31         };
32         this.ws.onerror = function () {
33             // on error
34             self.xynt_streaming.log("onerror");
35             self.ws_cb("error");
36         };
37     }
38     catch (ex) {
39         throw "websocket creation failed";
40     }
41
42     this.stopped = false;
43 }
44
45 transport_ws.prototype = {
46     doc: null,
47     xynt_streaming: "ready",
48     ws: null,
49     stopped: true,
50     failed: false,
51
52     ctx_old: "",
53     ctx_old_len: 0,
54     ctx_new: "",
55
56     // script_clean: 0,
57
58     destroy: function () { /* public */
59         if (this.ws != null) {
60             this.ws_abort();
61         }
62         delete this.ws;
63     },
64
65     ws_cb: function (from) {
66         var ret;
67
68         if (from == "error") {
69             if (this.xynt_streaming != "ready") {
70                 if (this.xynt_streaming.transp_fback > 0) {
71                     this.xynt_streaming.transp_fback--;
72                     this.stopped = true;
73                     this.xynt_streaming.reload();
74                 }
75             }
76         }
77         if (this.ws != null && this.ws.readyState > 1) {
78             this.stopped = true;
79         }
80     },
81
82     ws_abort: function() {
83         if (this.ws != null) {
84             this.ws.close();
85         }
86     },
87
88     xstr_is_init: function () { /* public */
89         return (true);
90     },
91
92     /* only after a successfull is_initialized call */
93     xstr_is_ready: function () { /* public */
94         return (this.ws.readyState == 1);
95     },
96
97     xstr_set: function () { /* public */
98         // already set
99     },
100
101     ctx_new_is_set: function () { /* public */
102         return (this.ctx_new != null);
103     },
104
105     ctx_new_curlen_get: function () { /* public */
106         return (this.ctx_new.length);
107     },
108
109     ctx_new_getchar: function(idx) { /* public */
110         return (this.ctx_new[idx]);
111     },
112
113     ctx_old_len_is_set: function () { /* public */
114         return (true);
115     },
116
117     ctx_old_len_get: function () { /* public */
118         return (this.ctx_old_len);
119     },
120
121     ctx_old_len_set: function (len) { /* public */
122         this.ctx_old_len = len;
123     },
124
125     ctx_old_len_add: function (len) { /* public */
126         this.ctx_old_len += len;
127     },
128
129     new_part: function () { /* public */
130         return (this.ctx_new.substr(this.ctx_old_len));
131     },
132
133     scrcls_set: function (step) { /* public */
134         // this.script_clean = step;
135     },
136
137     postproc: function () {
138         if (this.stopped && !this.xstr_is_ready()) {
139             this.xynt_streaming.reload();
140         }
141     }
142 }
143
144 //
145 // CLASS transport_xhr
146 //
147 function transport_xhr(doc, xynt_streaming, page)
148 {
149     this.doc = doc;
150     this.xynt_streaming = xynt_streaming;
151     this.xhr = createXMLHttpRequest();
152     this.xhr.open('GET', page);
153
154     var self = this;
155     this.xhr.onreadystatechange = function () { self.xhr_cb(); };
156     this.xhr.send(null);
157
158     this.stopped = false;
159 }
160
161 transport_xhr.prototype = {
162     doc: null,
163     xynt_streaming: "ready",
164     xhr: null,
165     stopped: true,
166
167     ctx_old: "",
168     ctx_old_len: 0,
169     ctx_new: null,
170
171     // script_clean: 0,
172
173     destroy: function () { /* public */
174         if (this.xhr != null) {
175             this.xhr_abort();
176         }
177         delete this.xhr;
178     },
179
180     xhr_cb: function () {
181         var ret;
182
183         if (this.xhr.readyState == 4) {
184             // console.log("SS: "+safestatus(xhr));
185
186             // NOTE: delay management later
187             // try {
188             //     if ((ret = safestatus(this.xhr)) == 200) {
189             //         this.delay = 0;
190             //         // console.log("del a null "+this.delayed);
191             //     } else if (ret != -1) {
192             //         this.delay = 5000;
193             //         this.hbit('X');
194             //         // alert('There was a problem with the request.' + ret);
195             //     }
196             // } catch(b) {};
197
198             // this.delayed = null;
199             this.stopped = true;
200         }
201     },
202
203     xhr_abort: function() {
204         if (this.xhr != null) {
205             this.xhr.abort();
206         }
207     },
208
209     xstr_is_init: function () { /* public */
210         try {
211             if (this.xhr.responseText != null) {
212                 this.ctx_new = this.xhr.responseText;
213             }
214         }
215         catch (e) {
216         }
217
218         return (this.ctx_new != null);
219     },
220
221     /* only after a successfull is_initialized call */
222     xstr_is_ready: function () { /* public */
223         return (this.xynt_streaming == "ready");
224     },
225
226     xstr_set: function () { /* public */
227         // already set
228     },
229
230     ctx_new_is_set: function () { /* public */
231         return (this.ctx_new != null);
232     },
233
234     ctx_new_curlen_get: function () { /* public */
235         return (this.ctx_new.length);
236     },
237
238     ctx_new_getchar: function(idx) { /* public */
239         return (this.ctx_new[idx]);
240     },
241
242     ctx_old_len_is_set: function () { /* public */
243         return (true);
244     },
245
246     ctx_old_len_get: function () { /* public */
247         return (this.ctx_old_len);
248     },
249
250     ctx_old_len_set: function (len) { /* public */
251         this.ctx_old_len = len;
252     },
253
254     ctx_old_len_add: function (len) { /* public */
255         this.ctx_old_len += len;
256     },
257
258     new_part: function () { /* public */
259         return (this.ctx_new.substr(this.ctx_old_len));
260     },
261
262     scrcls_set: function (step) { /* public */
263         // this.script_clean = step;
264     },
265
266     postproc: function () {
267         if (this.stopped && !this.xstr_is_ready()) {
268             this.xynt_streaming.reload();
269         }
270     }
271 }
272
273 //
274 // CLASS transport_htmlfile
275 //
276 function transport_htmlfile(doc, xynt_streaming, page)
277 {
278     this.doc = doc;
279     this.xynt_streaming = xynt_streaming;
280     this.transfdoc = new ActiveXObject("htmlfile");
281     this.transfdoc.open();
282     this.transfdoc.write("<html><body><iframe id='iframe'></iframe></body></html>");
283     this.transfdoc.close();
284
285     this.ifra = this.transfdoc.getElementById("iframe");
286     this.ifra.contentWindow.location.href = page;
287     this.stopped = false;
288 }
289
290 transport_htmlfile.prototype = {
291     doc: null,
292     xynt_streaming: null,
293     stopped: true,
294     ifra: null,
295     tradoc: null,
296
297     destroy: function () { /* public */
298         if (this.ifra != null) {
299         //     this.doc.body.removeChild(this.ifra);
300         //     delete this.ifra;
301              this.ifra = null;
302         }
303
304         if (this.transfdoc) {
305             delete this.transfdoc;
306             this.transfdoc = null;
307         }
308     },
309
310     xstr_is_init: function () { /* public */
311         return (typeof(this.ifra.contentWindow.xynt_streaming) != 'undefined');
312     },
313
314     /* only after a successfull is_initialized call */
315     xstr_is_ready: function () { /* public */
316         return (this.ifra.contentWindow.xynt_streaming == "ready");
317     },
318
319     /* only after a successfull is_initialized call */
320     xstr_set: function () { /* public */
321         if (this.ifra.contentWindow.xynt_streaming == "ready") {
322             this.ifra.contentWindow.xynt_streaming = this.xynt_streaming;
323             return (true);
324         }
325         else if (this.ifra.contentWindow.xynt_streaming == this.xynt_streaming) {
326             return (true);
327         }
328         else {
329             return (false);
330         }
331     },
332
333     ctx_new_is_set: function () { /* public */
334         return (typeof(this.ifra.contentWindow.ctx_new) != 'undefined');
335     },
336
337     ctx_new_curlen_get: function () { /* public */
338         return (this.ifra.contentWindow.ctx_new.length);
339     },
340
341     ctx_new_getchar: function(idx) { /* public */
342         return (this.ifra.contentWindow.ctx_new.charAt(idx));
343     },
344
345     ctx_old_len_is_set: function () { /* public */
346         return (typeof(this.ifra.contentWindow.ctx_old_len) != 'undefined');
347     },
348
349     ctx_old_len_get: function () { /* public */
350         return (this.ifra.contentWindow.ctx_old_len);
351     },
352
353     ctx_old_len_set: function (len) { /* public */
354         this.ifra.contentWindow.ctx_old_len = len;
355     },
356
357     ctx_old_len_add: function (len) { /* public */
358         this.ifra.contentWindow.ctx_old_len += len;
359     },
360
361     new_part: function () { /* public */
362         return (this.ifra.contentWindow.ctx_new.substr(this.ifra.contentWindow.ctx_old_len));
363     },
364
365     scrcls_set: function (step) { /* public */
366         this.ifra.contentWindow.script_clean = step;
367     },
368
369     postproc: function () { /* public */
370         if (this.stopped && !this.xstr_is_ready()) {
371             this.xynt_streaming.reload();
372         }
373     }
374 }
375
376 //
377 // CLASS transport_iframe
378 //
379 function transport_iframe(doc, xynt_streaming, page)
380 {
381     this.doc = doc;
382     this.xynt_streaming = xynt_streaming;
383     this.ifra = doc.createElement("iframe");
384     this.ifra.style.visibility = "hidden";
385     doc.body.appendChild(this.ifra);
386     this.ifra.contentWindow.location.href = page;
387     this.stopped = false;
388 }
389
390 transport_iframe.prototype = {
391     doc: null,
392     xynt_streaming: null,
393     stopped: true,
394     ifra: null,
395
396     destroy: function () { /* public */
397         try {
398             if (this.ifra != null) {
399                 // NOTE:  on Opera this remove child crash js if called from
400                 //        inside of the iframe, on IE on Windows without
401                 //        it stream abort fails.
402                 //        the problem is fixed setting into the iframe's onload
403                 //        function the stopped attribute to true and delegate
404                 //        postproc() fired by xynt_streaming watchdog()
405                 this.doc.body.removeChild(this.ifra);
406                 delete this.ifra;
407                 this.ifra = null;
408             }
409         } catch (b) {
410             alert("destroy exception catched");
411         }
412     },
413
414     xstr_is_init: function () { /* public */
415         return (typeof(this.ifra.contentWindow.xynt_streaming) != 'undefined');
416     },
417
418     /* only after a successfull is_initialized call */
419     xstr_is_ready: function () { /* public */
420         return (this.ifra.contentWindow.xynt_streaming == "ready");
421     },
422
423     /* only after a successfull is_initialized call */
424     xstr_set: function () { /* public */
425         if (this.ifra.contentWindow.xynt_streaming == "ready") {
426             this.ifra.contentWindow.xynt_streaming = this.xynt_streaming;
427             return (true);
428         }
429         else if (this.ifra.contentWindow.xynt_streaming == this.xynt_streaming) {
430             return (true);
431         }
432         else {
433             return (false);
434         }
435     },
436
437
438     /* only after a successfull is_ready call to be sure the accessibility of the var */
439     xstr_set_old: function (xynt_streaming) { /* public */
440         this.ifra.contentWindow.xynt_streaming = xynt_streaming;
441     },
442
443     ctx_new_is_set: function () { /* public */
444         return (typeof(this.ifra.contentWindow.ctx_new) != 'undefined');
445     },
446
447     ctx_new_curlen_get: function () { /* public */
448         return (this.ifra.contentWindow.ctx_new.length);
449     },
450
451     ctx_new_getchar: function(idx) { /* public */
452         return (this.ifra.contentWindow.ctx_new.charAt(idx));
453     },
454
455     ctx_old_len_is_set: function () { /* public */
456         return (typeof(this.ifra.contentWindow.ctx_old_len) != 'undefined');
457     },
458
459     ctx_old_len_get: function () { /* public */
460         return (this.ifra.contentWindow.ctx_old_len);
461     },
462
463     ctx_old_len_set: function (len) { /* public */
464         this.ifra.contentWindow.ctx_old_len = len;
465     },
466
467     ctx_old_len_add: function (len) { /* public */
468         this.ifra.contentWindow.ctx_old_len += len;
469     },
470
471     new_part: function () { /* public */
472         return (this.ifra.contentWindow.ctx_new.substr(this.ifra.contentWindow.ctx_old_len));
473     },
474
475     scrcls_set: function (step) { /* public */
476         this.ifra.contentWindow.script_clean = step;
477     },
478
479     postproc: function () { /* public */
480         if (this.stopped && !this.xstr_is_ready()) {
481             this.xynt_streaming.reload();
482         }
483     }
484 }
485
486 function xynt_streaming(win, transp_type, transp_port, transp_fback, console, gst, from, cookiename, sess, sandbox, page, cmdproc)
487 {
488     this.win = win;
489     this.transp_type = transp_type;
490     this.transp_port = transp_port;
491     this.transp_fback = transp_fback;
492     this.console = console;
493     this.gst = gst;
494     this.from = from;
495     this.cookiename = cookiename;
496     this.sess = sess;
497     this.sandbox = sandbox;
498     this.page = page;
499     this.cmdproc = cmdproc;
500     // this.cmdproc = function(com){/* console.log("COM: "+com); */ eval(com);}
501     this.doc = win.document;
502     this.keepalive_old = -1;
503     this.keepalive_new = -1;
504
505     this.mon_errtime = this.keepalives_eq_max * this.watchdog_checktm * this.watchdog_timeout;
506     this.mon_wrntime = this.mon_errtime / 2;
507
508     this.mon_update();
509 }
510
511 xynt_streaming.prototype = {
512     win:               null,
513     transp_type:       null,
514     transp_port:         80,
515     transp_fback:         0,
516     transp:            null,
517     console:           null,
518     gst:               null,
519     from:              null,
520     cookiename:        null,
521     sess:              null,
522     sandbox:           null,
523     page:              null,
524     cmdproc:           null,
525
526     start_time:        0,
527     restart_wait:      5000, // wait restart_wait millisec before begin to check if restart is needed
528
529     doc:               null,
530     cookiepath: "/brisk/",
531     watchdog_hdl:      null,
532     hbit:              function () {},
533     keepalive_old:    -1,
534     keepalive_new:    -1,
535     keepalives_equal:  0,
536     /* NOTE: right watch_timeout value to 100, for devel reasons use 1000 or more */
537     /* restart after  4 * 40 * 100 millisec if server ping is missing => 16secs */
538     keepalives_eq_max: 4,
539     watchdog_checktm:  40,
540     watchdog_timeout:  100,
541     watchdog_ct:       0,
542     watchable:         false,
543     restart_n:         0,
544     comm_match:        /_*@BEGIN@(.*?)@END@/g,
545     comm_clean:        /_*@BEGIN@(.*?)@END@/,
546     stream:            "",
547     the_end:           false,
548
549     mon_time:         -1,
550     mon_wrntime:       0,
551     mon_errtime:       0,
552
553     mon_stat_old:      "",
554
555     mon_update: function()
556     {
557         var date = new Date();
558
559         this.mon_time = date.getTime();
560     },
561
562     /*
563       ping arrives at least every RD_KEEPALIVE_TOUT secs (currently 4 secs)
564
565       return values: 0 unknown
566                      1 ok
567                      2 warning
568                      3 error
569      */
570     mon_status: function()
571     {
572         var delta, date;
573
574         var date = new Date();
575
576         delta = date.getTime() - this.mon_time;
577
578         if (delta < this.mon_wrntime)
579             return 1;
580         else if (delta < this.mon_errtime)
581             return 2;
582         else
583             return 3;
584     },
585
586     start: function() { /* public */
587         var transp_type;
588         var page;
589
590         // this.log("start "+this.transp_type+" "+this.transp_fback);
591         if (this.the_end)
592             return;
593
594         createCookie(this.cookiename, sess, 24*365, this.cookiepath);
595         // alert("start");
596         this.log("xynt_streaming:start restart: "+this.restart_n);
597         this.keepalives_equal = 0;
598
599         // page arrangement
600         this.page = url_complete(this.win.location.href, this.page);
601
602         if (this.transp_fback > 0) {
603             transp_type = "websocket";
604             transp_port = (this.transp_fback == 2 ? 80 : 8080);
605         }
606         else {
607             transp_type = this.transp_type;
608             transp_port = this.transp_port;
609         }
610
611         if (transp_type == "websocket") {
612             var end_proto, first_slash;
613
614             // change protocol
615             this.log("precha ["+this.page+"]");
616             end_proto = this.page.indexOf("://");
617             first_slash = this.page.substring(end_proto+3).indexOf("/");
618
619             page = "ws://" + this.page.substring(end_proto+3, end_proto+3+first_slash) + ":" + transp_port + this.page.substring(end_proto+3 + first_slash);
620         }
621         else {
622             page = this.page;
623         }
624         // stat, subst, this.gst.st
625
626         page = url_append_args(page, "sess", this.sess, "stat", stat, "subst", subst, "step", this.gst.st, "from", this.from);
627         // this.log("the page:");
628         // this.log(page);
629
630         try {
631             // transport instantiation
632             if (transp_type == "websocket") {
633                 page = url_append_args(page, "transp", "websocket");
634                 this.transp = new transport_ws(this.doc, this, page);
635             }
636             else if (transp_type == "xhr") {
637                 page = url_append_args(page, "transp", "xhr");
638                 this.transp = new transport_xhr(this.doc, this, page);
639             }
640             else if (transp_type == "iframe") {
641                 page = url_append_args(page, "transp", "iframe");
642                 this.transp = new transport_iframe(this.doc, this, page);
643             }
644             else if (transp_type == "htmlfile") {
645                 page = url_append_args(page, "transp", "htmlfile");
646                 this.transp = new transport_htmlfile(this.doc, this, page);
647             }
648             else
649                 return;
650         }
651         catch (err) {
652             if (this.transp_fback > 0) {
653                 this.transp_fback--;
654                 this.start();
655                 return;
656             }
657         }
658
659         // watchdog setting
660         this.watchdog_ct  = 0;
661         if (!this.the_end) {
662             this.watchdog_hdl = setTimeout(function(obj) { obj.log("tout1"); obj.watchdog(); }, this.watchdog_timeout, this);
663         }
664
665         var date = new Date();
666         this.start_time = date.getTime();
667     },
668
669     stop: function() {
670         this.the_end = true;
671         this.abort();
672     },
673
674     hbit_set: function (hbit) {
675         this.hbit = hbit;
676     },
677
678
679     hbit_status: function () {
680         var ret;
681
682         ret = this.mon_status();
683         // console.log("mon_status: "+ret+" 0: "+this.mon_time);
684         switch (ret) {
685         case 0:
686             mon_stat = "b";
687             break;
688         case 1:
689             mon_stat = "g";
690             break;
691         case 2:
692             mon_stat = "y";
693             break;
694         case 3:
695             mon_stat = "r";
696             break;
697         }
698
699         if (this.mon_stat_old != mon_stat) {
700             this.hbit(mon_stat);
701             this.mon_stat_old = mon_stat;
702         }
703     },
704
705
706     watchdog: function () {
707         // alert("watchdog");
708         var i, again;
709         var comm_newpart, comm_len, comm_arr;
710         var ctx_new_len;
711
712         if (this.sandbox != null) {
713             // from old: var zug = "POLL sess = "+sess+" stat = "+stat+" subst = "+subst+" step = "+this.gst.st+" step_loc = "+this.gst.st_loc+" step_loc_new = "+this.gst.st_loc_new+" STOP: "+this.stopped;
714             var zug = "WATCHDOG  sess = ["+this.sess+"]  step = "+this.gst.st+" step_loc = "+this.gst.st_loc+" step_loc_new = "+this.gst.st_loc_new;
715             if (zug != this.sandbox.innerHTML)
716                 this.sandbox.innerHTML = zug;
717         }
718
719         // WATCHDOGING THE CONNECTION
720         this.log("hs::watchdog: start, cur equal times: "+this.keepalives_equal);
721         if (!this.watchable) {
722             do {
723                 try{
724                     // if (typeof(this.ifra.contentWindow.xynt_streaming) == 'undefined')
725                     if (!this.transp.xstr_is_init()) {
726                         this.log("hs::watchdog: xstr_is_init = false");
727                         break;
728                     }
729                 }
730                 catch(b) {
731                     this.log("hs::watchdog: exception");
732                     break;
733                 }
734
735                 /*
736                   on IE7 the the window frame scope is cleaned after the href is set, so we wait
737                   for a well know variable value before assign this object value to it (OO is a passion)
738                 */
739                 // if (this.ifra.contentWindow.xynt_streaming == "ready") {
740                 if (this.transp.xstr_set()) {
741                     // this.ifra.contentWindow.xynt_streaming = this;
742                     this.watchable = true;
743                     this.watchdog_ct = 0;
744                     this.log("hs::watchdog: watchable = yes");
745                 }
746             } while (false);
747         }
748         if ( (this.watchdog_ct % this.watchdog_checktm) == 0) {
749             this.log("hs::watchdog: this.keepalive_old: "+this.keepalive_old+" this.keepalive_new: "+this.keepalive_new);
750             if (this.keepalive_old == this.keepalive_new) {
751                 this.keepalives_equal++;
752             }
753             else {
754                 this.keepalive_old = this.keepalive_new;
755                 this.keepalives_equal = 0;
756             }
757
758             if (this.keepalives_equal >= this.keepalives_eq_max) {
759                 this.log("hs::watchdog: MAX ACHIEVED "+this.keepalives_equal);
760                 this.reload();
761                 // alert("watchdog return reload");
762                 this.hbit_status();
763                 return;
764             }
765         }
766
767         // PICK COMMANDS FROM STREAM
768         do {
769             // alert("do--while begin ["+again+"]");
770             // CHECK: maybe again here isn't needed
771             again = 0;
772             try {
773                 /* if (typeof(this.ifra.contentWindow.ctx_new)     == 'undefined' ||
774                    typeof(this.ifra.contentWindow.ctx_old_len) == 'undefined') */
775                 if (!this.transp.ctx_new_is_set() || !this.transp.ctx_old_len_is_set())
776                     break;
777             }
778             catch(b) {
779                 break;
780             }
781
782             // ctx_new_len = this.ifra.contentWindow.ctx_new.length;
783             ctx_new_len = this.transp.ctx_new_curlen_get();
784             // if (ctx_new_len <= this.ifra.contentWindow.ctx_old_len) {
785             if (ctx_new_len <= this.transp.ctx_old_len_get()) {
786                 break;
787             }
788             this.log("new: "+ ctx_new_len + "  old: "+this.transp.ctx_old_len_get());
789             this.keepalive_new++;
790             // alert("pre-loop 1");
791             for (i = this.transp.ctx_old_len_get() ; i < ctx_new_len ; i++) {
792                 // if (this.ifra.contentWindow.ctx_new.charAt(i) != '_') {
793                 if (this.transp.ctx_new_getchar(i) != '_') {
794                     // this.log("ctx_new.char(i) != '_' ["+this.ifra.contentWindow.ctx_new.charAt(i)+"]");
795                     break;
796                 }
797                 this.mon_update();
798                 this.hbit_status();
799
800                 // else {
801                 //     this.log("ctx_new.charAt(i) == '_'");
802                 // }
803             }
804             // this.ifra.contentWindow.ctx_old_len = i;
805             this.transp.ctx_old_len_set(i);
806             if (i == ctx_new_len) {
807                 this.log("old_len == i");
808                 break;
809             }
810             else {
811                 this.log("old_len != i: "+i);
812             }
813             // alert("do--while middle ["+this.ifra.contentWindow.ctx_old_len+"]");
814
815             comm_newpart = this.transp.new_part();
816             this.log("COM_NEWPART: ["+comm_newpart+"]");
817             comm_len = 0;
818             comm_arr = comm_newpart.match(this.comm_match);
819
820             // alert("do--while middle2 ["+again+"]");
821             if (comm_arr) {
822                 var comm_arr_len = comm_arr.length;
823                 for (i = 0 ; i < comm_arr_len ; i++) {
824                     var temp = comm_arr[i].replace(this.comm_clean,"$1").split("|");
825                     this.gst.comms = this.gst.comms.concat(temp);
826                     comm_len += comm_arr[i].length;
827                 }
828                 again = 1;
829                 this.mon_update();
830                 this.hbit_status();
831             }
832             // this.ifra.contentWindow.ctx_old_len += comm_len;
833             this.transp.ctx_old_len_add(comm_len);
834             // this.ifra.contentWindow.script_clean = this.gst.st;
835             this.transp.scrcls_set(this.gst.st);
836             // alert("do--while end ["+again+"]");
837         } while (again);
838
839         // alert("post while");
840         // EXECUTION OF STREAM COMMANDS
841         do {
842             again = 0;
843             //MOP ?? xhrrestart = 0;
844             if (this.gst.st_loc < this.gst.st_loc_new) {
845                 // there is some slow actions running
846                 break;
847             }
848             else if (this.gst.comms.length > 0) {
849                 var singlecomm;
850
851                 singlecomm = this.gst.comms.shift();
852                 // alert("EXE"+gugu);
853                 // $("xhrdeltalog").innerHTML = "EVALL: "+singlecomm.replace("<", "&lt;", "g"); +"<br>";
854                 //xx this.hbit("+");
855
856                 // alert("SINGLE: ["+singlecomm+"]");
857                 this.cmdproc(singlecomm);
858                 again = 1;
859             }
860         } while (again);
861         this.watchdog_ct++;
862         if (!this.the_end) {
863             var date = new Date();
864             if (date.getTime() > (this.start_time + this.restart_wait)) {
865                 this.transp.postproc();
866             }
867             this.watchdog_hdl = setTimeout(function(obj) { /* obj.log("tout2"); */ obj.watchdog(); }, this.watchdog_timeout, this);
868             this.hbit_status();
869         }
870         // alert("watchdog return normal");
871
872         return;
873     },
874
875     //
876     // moved to xynt-streaming-ifra as push()
877     //
878     // keepalive: function (s) {
879     //     this.log("hs::keepalive");
880     //     if (s != null) {
881     //         this.log(s);
882     //         this.ifra.contentWindow.ctx_new += "@BEGIN@"+s+"@END@";
883     //     }
884     //     else {
885     //         this.ifra.contentWindow.ctx_new += "_";
886     //     }
887     //     // this.keepalive_new++;
888     // },
889
890     abort: function () { /* public */
891         // this.log("PATH: "+this.ifra.contentWindow.location.protocol + "://" + this.ifra.contentWindow.location.host + "/" + this.ifra.contentWindow.location.pathname);
892
893         this.gst.abort();
894         if (this.watchdog_hdl != null) {
895             clearTimeout(this.watchdog_hdl);
896             this.watchdog_hdl = null;
897         }
898
899         this.restart_n++;
900         this.log("hs::reload");
901         this.watchable = false;
902         if (this.transp != null) {
903             this.transp.destroy();
904             delete this.transp;
905             this.transp = null;
906         }
907     },
908
909     reload: function () {
910         this.abort();
911         this.start(null);
912     },
913
914     log: function (s) {
915         if (this.console != null) {
916             return (this.console.log(s));
917         }
918     }
919 }