X-Git-Url: https://mop.ddnsfree.com/gitweb/?a=blobdiff_plain;f=web%2Fxynt-streaming.js;h=009bb01ebd0561a33045fe9cb3cb9c5f4f9d5bcf;hb=e8903530a6cf61a0b06c63bbabed10a813fea097;hp=dc0043ebf6e72e67b5c9aed37875f6858585f95a;hpb=8fac461bc252da4aebf1fefbe25904251946bb6a;p=brisk.git diff --git a/web/xynt-streaming.js b/web/xynt-streaming.js index dc0043e..009bb01 100644 --- a/web/xynt-streaming.js +++ b/web/xynt-streaming.js @@ -1,10 +1,229 @@ // old targetpage == page and moved into start method +// +// CLASS transport_ws +// +function transport_ws(doc, xynt_streaming, page) +{ + // if four arguments manage if WS or WSS connection + if (arguments.length > 3) + this.is_secure = arguments[3]; + else + this.is_secure = false; + + if (this.is_secure) + this.name = "WebSocketSecure"; + else + this.name = "WebSocket"; + this.ctx_new = ""; + this.out_queue = []; + var self = this; + + this.doc = doc; + this.failed = false; + this.xynt_streaming = xynt_streaming; + try { + this.xynt_streaming.log("PAGE: "+page); + this.ws = new WebSocket(page); + this.ws.onopen = function () { + console.log('WS On open'); + + self.xynt_streaming.log("onopen"); + if (this.readyState == 1) { + // connected + self.ws_cb("open"); + self.init_steps = 1; + } + }; + this.ws.onmessage = function (msg) { + console.log('WS On message'); + self.xynt_streaming.log("onmessage"); + // new data in msg.data + self.ctx_new += msg.data; + }; + this.ws.onclose = function (msg) { + console.log('WS On close'); + self.onopen = null; + self.onclose = null; + self.onerror = null; + self.xynt_streaming.log("onclose"+self.init_steps); + if (self.init_steps == 0) + self.ws_cb("error"); + else + self.ws_cb("close"); + }; + this.ws.onerror = function () { + // on error + this.onopen = null; + this.onclose = null; + this.onerror = null; + self.xynt_streaming.log("onerror"); + self.ws_cb("error"); + }; + } + catch (ex) { + throw "websocket creation failed"; + } + + this.stopped = false; +} + +transport_ws.prototype = { + doc: null, + name: null, + xynt_streaming: "ready", + ws: null, + out_queue: null, + stopped: true, + failed: false, + + init_steps: 0, + + ctx_old: "", + ctx_old_len: 0, + ctx_new: "", + + // script_clean: 0, + + destroy: function () { /* public */ + if (this.ws != null) { + this.ws_abort(); + } + delete this.ws; + }, + + ws_cb: function (from) { + var ret; + + if (from == "error") { + if (this.xynt_streaming != "ready") { + if (this.xynt_streaming.transp_fback > 0) { +this.xynt_streaming.log("DEC: "+this.xynt_streaming.transp_fback); + this.xynt_streaming.transp_fback--; + this.stopped = true; + this.xynt_streaming.reload(); + } + } + } + else if (from == "open") { + this.flush_out_queue(); + } + + if (this.ws != null && this.ws.readyState > 1) { + this.stopped = true; + } + }, + + flush_out_queue: function() { + var l_out = this.out_queue.length; + if (l_out == 0) + return; + + for (var i = 0 ; i < l_out ; i++) { + if (this.ws.readyState != 1) { + break; + } + var item = this.out_queue.shift(); + var sent = true; + try { + this.ws.send(item); + } + catch (ex) { + this.out_queue.unshift(item); + break; + } + } + }, + + send: function(msg) { + console.log('new send'); + if (this.ws && this.ws.readyState == 1) { + try { + console.log('Try send ... '); + this.flush_out_queue(); + this.ws.send(msg); + console.log(' ... done'); + } + catch (ex) { + console.log(' ... catched exception'); + this.flush_out.push(msg); + } + } + else { + console.log('ws not ready: push into flush_out'); + this.flush_out.push(msg); + } + }, + + ws_abort: function() { + if (this.ws != null) { +this.xynt_streaming.log("WSCLOSE"); + this.ws.close(); + } + }, + + xstr_is_init: function () { /* public */ + return (true); + }, + + /* only after a successfull is_initialized call */ + xstr_is_ready: function () { /* public */ + return (this.ws.readyState == 1); + }, + + xstr_set: function () { /* public */ + // already set + }, + + ctx_new_is_set: function () { /* public */ + return (this.ctx_new != null); + }, + + ctx_new_curlen_get: function () { /* public */ + return (this.ctx_new.length); + }, + + ctx_new_getchar: function(idx) { /* public */ + return (this.ctx_new[idx]); + }, + + ctx_old_len_is_set: function () { /* public */ + return (true); + }, + + ctx_old_len_get: function () { /* public */ + return (this.ctx_old_len); + }, + + ctx_old_len_set: function (len) { /* public */ + this.ctx_old_len = len; + }, + + ctx_old_len_add: function (len) { /* public */ + this.ctx_old_len += len; + }, + + new_part: function () { /* public */ + return (this.ctx_new.substr(this.ctx_old_len)); + }, + + scrcls_set: function (step) { /* public */ + // this.script_clean = step; + }, + + postproc: function () { + if (this.stopped && !this.xstr_is_ready()) { + this.xynt_streaming.reload(); + } + } +} + // // CLASS transport_xhr // function transport_xhr(doc, xynt_streaming, page) { + this.name = "XHR"; this.doc = doc; this.xynt_streaming = xynt_streaming; this.xhr = createXMLHttpRequest(); @@ -19,6 +238,7 @@ function transport_xhr(doc, xynt_streaming, page) transport_xhr.prototype = { doc: null, + name: null, xynt_streaming: "ready", xhr: null, stopped: true, @@ -134,6 +354,7 @@ transport_xhr.prototype = { // function transport_htmlfile(doc, xynt_streaming, page) { + this.name = "HTMLFile"; this.doc = doc; this.xynt_streaming = xynt_streaming; this.transfdoc = new ActiveXObject("htmlfile"); @@ -148,6 +369,7 @@ function transport_htmlfile(doc, xynt_streaming, page) transport_htmlfile.prototype = { doc: null, + name: null, xynt_streaming: null, stopped: true, ifra: null, @@ -198,8 +420,7 @@ transport_htmlfile.prototype = { }, ctx_new_getchar: function(idx) { /* public */ - return (this.ifra.contentWindow.ctx_new.charAt(idx)); - + return (this.ifra.contentWindow.ctx_new.charAt(idx)); }, ctx_old_len_is_set: function () { /* public */ @@ -233,13 +454,12 @@ transport_htmlfile.prototype = { } } - - // // CLASS transport_iframe // function transport_iframe(doc, xynt_streaming, page) { + this.name = "IFRAME"; this.doc = doc; this.xynt_streaming = xynt_streaming; this.ifra = doc.createElement("iframe"); @@ -251,6 +471,7 @@ function transport_iframe(doc, xynt_streaming, page) transport_iframe.prototype = { doc: null, + name: null, xynt_streaming: null, stopped: true, ifra: null, @@ -311,7 +532,7 @@ transport_iframe.prototype = { }, ctx_new_getchar: function(idx) { /* public */ - return (this.ifra.contentWindow.ctx_new.charAt(idx)); + return (this.ifra.contentWindow.ctx_new.charAt(idx)); }, ctx_old_len_is_set: function () { /* public */ @@ -345,10 +566,12 @@ transport_iframe.prototype = { } } -function xynt_streaming(win, transp_type, console, gst, from, cookiename, sess, sandbox, page, cmdproc) +function xynt_streaming(win, transp_type, transp_port, transp_fback, console, gst, from, cookiename, sess, sandbox, page, cmdproc) { this.win = win; this.transp_type = transp_type; + this.transp_port = transp_port; + this.transp_fback = transp_fback; this.console = console; this.gst = gst; this.from = from; @@ -361,11 +584,20 @@ function xynt_streaming(win, transp_type, console, gst, from, cookiename, sess, this.doc = win.document; this.keepalive_old = -1; this.keepalive_new = -1; + + this.mon_errtime = this.keepalives_eq_max * this.watchdog_checktm * this.watchdog_timeout; + this.mon_wrntime = this.mon_errtime / 2; + + this.mon_update(); } xynt_streaming.prototype = { win: null, transp_type: null, + transp_port: 80, + transp_type_cur: null, + transp_port_cur: 80, + transp_fback: 0, transp: null, console: null, gst: null, @@ -394,16 +626,54 @@ xynt_streaming.prototype = { watchdog_ct: 0, watchable: false, restart_n: 0, - comm_match: /_*@BEGIN@(.*?)@END@/g, + comm_match: /_*@BEGIN@(.*?)@END@/g, comm_clean: /_*@BEGIN@(.*?)@END@/, stream: "", the_end: false, - w_stat_old: "", - s_stat_old: "", + mon_time: -1, + mon_wrntime: 0, + mon_errtime: 0, + + mon_stat_old: "", + + mon_update: function() + { + var date = new Date(); + + this.mon_time = date.getTime(); + }, + + /* + ping arrives at least every RD_KEEPALIVE_TOUT secs (currently 4 secs) + + return values: 0 unknown + 1 ok + 2 warning + 3 error + */ + mon_status: function() + { + var delta, date; + + var date = new Date(); + + delta = date.getTime() - this.mon_time; + + if (delta < this.mon_wrntime) + return 1; + else if (delta < this.mon_errtime) + return 2; + else + return 3; + }, start: function() { /* public */ - if (this.the_end) + var transp_type; + var page; + + // this.log("start "+this.transp_type+" "+this.transp_fback); + if (this.the_end) return; createCookie(this.cookiename, sess, 24*365, this.cookiepath); @@ -413,26 +683,87 @@ xynt_streaming.prototype = { // page arrangement this.page = url_complete(this.win.location.href, this.page); - // stat, subst, this.gst.st - this.page = url_append_args(this.page, "sess", this.sess, "stat", stat, "subst", subst, "step", this.gst.st, "from", this.from); - this.log(this.page); + // DEFAULT TRANSPORT PROTOCOL HERE websocketsec, websocket + if (this.transp_fback > 0) { + if (location.protocol == 'https:') { + transp_type = "websocketsec"; + transp_port = 443; + } + else { + transp_type = "websocket"; + transp_port = (this.transp_fback == 2 ? 80 : 8080); + } + + } + else { + transp_type = this.transp_type; + transp_port = this.transp_port; + } + + this.transp_type_cur = transp_type; + this.transp_port_cur = transp_port; + + if (transp_type == "websocket" || transp_type == "websocketsec") { + var end_proto, first_slash, newpage; + + // change protocol + this.log("precha ["+this.page+"]"); + if (transp_type == "websocketsec") { + newpage = this.page.replace(/\.php$/g, "_wss.php").replace(/\.php\?/g, "_wss.php?"); + } + else { + newpage = this.page; + } + end_proto = newpage.indexOf("://"); + first_slash = newpage.substring(end_proto+3).indexOf("/"); - // transport instantiation - if (this.transp_type == "xhr") { - this.page = url_append_args(this.page, "transp", "xhr"); - this.transp = new transport_xhr(this.doc, this, this.page); + page = (transp_type == "websocketsec" ? "wss://" : "ws://") + + newpage.substring(end_proto+3, end_proto+3 + first_slash) + ":" + + transp_port + newpage.substring(end_proto+3 + first_slash); + // this.log("MOP WS: " + page); + } + else { + page = this.page; } - else if (this.transp_type == "iframe") { - this.page = url_append_args(this.page, "transp", "iframe"); - this.transp = new transport_iframe(this.doc, this, this.page); + // stat, subst, this.gst.st + + page = url_append_args(page, "sess", this.sess, "stat", stat, "subst", subst, "step", this.gst.st, "from", this.from); + // this.log("the page:"); + // this.log(page); + + try { + // transport instantiation + if (transp_type == "websocketsec") { + page = url_append_args(page, "transp", "websocketsec"); + this.transp = new transport_ws(this.doc, this, page, true); + } + else if (transp_type == "websocket") { + page = url_append_args(page, "transp", "websocket"); + this.transp = new transport_ws(this.doc, this, page); + } + else if (transp_type == "xhr") { + page = url_append_args(page, "transp", "xhr"); + this.transp = new transport_xhr(this.doc, this, page); + } + else if (transp_type == "iframe") { + page = url_append_args(page, "transp", "iframe"); + this.transp = new transport_iframe(this.doc, this, page); + } + else if (transp_type == "htmlfile") { + page = url_append_args(page, "transp", "htmlfile"); + this.transp = new transport_htmlfile(this.doc, this, page); + } + else + return; } - else if (this.transp_type == "htmlfile") { - this.page = url_append_args(this.page, "transp", "htmlfile"); - this.transp = new transport_htmlfile(this.doc, this, this.page); + catch (err) { + if (this.transp_fback > 0) { + this.transp_fback--; + this.start(); + return; + } } - else - return; // watchdog setting this.watchdog_ct = 0; @@ -453,47 +784,42 @@ xynt_streaming.prototype = { this.hbit = hbit; }, + hbit_status: function () { - if (this.watchdog_hdl) - w_stat = "g"; - else - w_stat = "r"; + var ret; - if (this.transp.ctx_new_is_set() && - this.transp.ctx_new_curlen_get() > 0) { - if (this.keepalives_equal == 0) { - s_stat = "g"; - } - else if (this.keepalives_equal < this.keepalives_eq_max) { - s_stat = "y"; - } - else { - s_stat = "r"; - } - } - else { - s_stat = "r"; + ret = this.mon_status(); + // console.log("mon_status: "+ret+" 0: "+this.mon_time); + switch (ret) { + case 0: + mon_stat = "b"; + break; + case 1: + mon_stat = "g"; + break; + case 2: + mon_stat = "y"; + break; + case 3: + mon_stat = "r"; + break; } - if (this.s_stat_old != s_stat || - this.w_stat_old != w_stat) - this.hbit(s_stat, w_stat); - this.s_stat_old = s_stat; - this.w_stat_old = w_stat; + if (this.mon_stat_old != mon_stat) { + this.hbit(mon_stat); + this.mon_stat_old = mon_stat; + } }, + watchdog: function () { // alert("watchdog"); var i, again; var comm_newpart, comm_len, comm_arr; var ctx_new_len; - this.watchdog_hdl = null; - - this.hbit_status(); if (this.sandbox != null) { - // 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; - var zug = "WATCHDOG sess = ["+this.sess+"] step = "+this.gst.st+" step_loc = "+this.gst.st_loc+" step_loc_new = "+this.gst.st_loc_new; + var zug = "WATCHDOG sess = ["+this.sess+"] step = "+this.gst.st+" step_loc = "+this.gst.st_loc+" step_loc_new = "+this.gst.st_loc_new+"Transport: "+this.transp.name; if (zug != this.sandbox.innerHTML) this.sandbox.innerHTML = zug; } @@ -515,7 +841,7 @@ xynt_streaming.prototype = { } /* - on IE7 the the window frame scope is cleaned after the href is set, so we wait + on IE7 the the window frame scope is cleaned after the href is set, so we wait for a well know variable value before assign this object value to it (OO is a passion) */ // if (this.ifra.contentWindow.xynt_streaming == "ready") { @@ -529,8 +855,6 @@ xynt_streaming.prototype = { } if ( (this.watchdog_ct % this.watchdog_checktm) == 0) { this.log("hs::watchdog: this.keepalive_old: "+this.keepalive_old+" this.keepalive_new: "+this.keepalive_new); - - // alert("qui "+this.transp.ctx_new_curlen_get()+" "+this.transp.ctx_old_len_get(); if (this.keepalive_old == this.keepalive_new) { this.keepalives_equal++; } @@ -538,11 +862,12 @@ xynt_streaming.prototype = { this.keepalive_old = this.keepalive_new; this.keepalives_equal = 0; } - + if (this.keepalives_equal >= this.keepalives_eq_max) { this.log("hs::watchdog: MAX ACHIEVED "+this.keepalives_equal); this.reload(); // alert("watchdog return reload"); + this.hbit_status(); return; } } @@ -550,7 +875,7 @@ xynt_streaming.prototype = { // PICK COMMANDS FROM STREAM do { // alert("do--while begin ["+again+"]"); - // CHECK: maybe again here isn't needed + // CHECK: maybe again here isn't needed again = 0; try { /* if (typeof(this.ifra.contentWindow.ctx_new) == 'undefined' || @@ -561,9 +886,9 @@ xynt_streaming.prototype = { catch(b) { break; } + // ctx_new_len = this.ifra.contentWindow.ctx_new.length; ctx_new_len = this.transp.ctx_new_curlen_get(); - this.log("new_len: "+ ctx_new_len); // if (ctx_new_len <= this.ifra.contentWindow.ctx_old_len) { if (ctx_new_len <= this.transp.ctx_old_len_get()) { break; @@ -572,12 +897,14 @@ xynt_streaming.prototype = { this.keepalive_new++; // alert("pre-loop 1"); for (i = this.transp.ctx_old_len_get() ; i < ctx_new_len ; i++) { - // alert("ctx_new_getchar: "+this.transp.ctx_new_getchar(i)); - + // if (this.ifra.contentWindow.ctx_new.charAt(i) != '_') { if (this.transp.ctx_new_getchar(i) != '_') { // this.log("ctx_new.char(i) != '_' ["+this.ifra.contentWindow.ctx_new.charAt(i)+"]"); break; } + this.mon_update(); + this.hbit_status(); + // else { // this.log("ctx_new.charAt(i) == '_'"); // } @@ -607,6 +934,8 @@ xynt_streaming.prototype = { comm_len += comm_arr[i].length; } again = 1; + this.mon_update(); + this.hbit_status(); } // this.ifra.contentWindow.ctx_old_len += comm_len; this.transp.ctx_old_len_add(comm_len); @@ -626,14 +955,19 @@ xynt_streaming.prototype = { } else if (this.gst.comms.length > 0) { var singlecomm; - + singlecomm = this.gst.comms.shift(); // alert("EXE"+gugu); // $("xhrdeltalog").innerHTML = "EVALL: "+singlecomm.replace("<", "<", "g"); +"
"; //xx this.hbit("+"); // alert("SINGLE: ["+singlecomm+"]"); + // window.console.log("["+singlecomm+"]"); this.cmdproc(singlecomm); + if (this.transp_type_cur) { + this.transp_type = this.transp_type_cur; + this.transp_port = this.transp_port_cur; + } again = 1; } } while (again); @@ -651,6 +985,15 @@ xynt_streaming.prototype = { return; }, + send: function(msg) { + if (typeof(this.transp.send) == 'undefined') { + this.log('send not implemented for ' + this.transp_type); + return; + } + + return this.transp.send(msg); + }, + // // moved to xynt-streaming-ifra as push() //