From bc8e3d4db75e693eceee74badf27ddb3f99bee22 Mon Sep 17 00:00:00 2001 From: Joel Martin Date: Thu, 1 Jul 2010 11:54:44 -0500 Subject: [PATCH] Opera fixes and big Opera performance boost. Add message/state pollling in web-socket-js. Since Opera tends to drop message events, we can dramatically increase performance by polling every now for message event data. Also, add more direct calls to update readyState so that it's not missed when Opera drops events. --- docs/TODO | 5 +- include/vnc.js | 2 +- include/web-socket-js/web_socket.js | 73 +++++++++++++++++++---------- 3 files changed, 51 insertions(+), 29 deletions(-) diff --git a/docs/TODO b/docs/TODO index b828ee0..2fa80c2 100644 --- a/docs/TODO +++ b/docs/TODO @@ -2,9 +2,6 @@ Short Term: - Test on IE 9 preview 3. -- Track down "INVALID_STATE_ERR" when reconnecting using - web-socket-js. - - Possibly support IE <= 8.0 using excanvas or fxcanvas: http://excanvas.sourceforge.net/ http://code.google.com/p/fxcanvas/ @@ -12,6 +9,8 @@ Short Term: - Timing delta between frames in proxy record log, for playback support (for demo and test). +- Track down hang in Opera after second disconnect. + Medium Term: diff --git a/include/vnc.js b/include/vnc.js index 4de8cef..dd26443 100644 --- a/include/vnc.js +++ b/include/vnc.js @@ -194,9 +194,9 @@ connect: function (host, port, password, encrypt, true_color) { disconnect: function () { //console.log(">> disconnect"); if ((RFB.ws) && (RFB.ws.readyState === WebSocket.OPEN)) { + RFB.ws.close(); RFB.updateState('closed'); RFB.ws.onmessage = function (e) { return; }; - RFB.ws.close(); } if (Canvas.ctx) { Canvas.stop(); diff --git a/include/web-socket-js/web_socket.js b/include/web-socket-js/web_socket.js index 6be794f..936a663 100755 --- a/include/web-socket-js/web_socket.js +++ b/include/web-socket-js/web_socket.js @@ -35,31 +35,7 @@ self.__flash = WebSocket.__flash.create(url, protocol, proxyHost || null, proxyPort || 0, headers || null); - self.__flash.addEventListener("open", function(fe) { - console.log("web-socket.js open"); - try { - if (self.onopen) { - self.onopen(); - } else { - // If "open" comes back in the same thread, then the - // caller will not have set the onopen handler yet. - setTimeout(function () { - if (self.onopen) { self.onopen(); } }, 10); - } - } catch (e) { - console.error(e.toString()); - } - }); - - self.__flash.addEventListener("close", function(fe) { - try { - if (self.onclose) self.onclose(); - } catch (e) { - console.error(e.toString()); - } - }); - - self.__flash.addEventListener("message", function(fe) { + self.__messageHandler = function() { var i, arr, data; arr = self.__flash.readSocketData(); for (i=0; i < arr.length; i++) { @@ -79,9 +55,53 @@ console.error(e.toString()); } } + }; + + self.__flash.addEventListener("open", function(fe) { + self.readyState = self.__flash.getReadyState(); + + // For browsers (like Opera) that drop events, also poll for + // message data + if (self.__messageHandlerID) { + clearInterval(self.__messageHandlerID); + } + self.__messageHandlerID = setInterval(function () { + //console.log("polling for message data"); + self.__messageHandler; }, 500); + + try { + if (self.onopen) { + self.onopen(); + } else { + // If "open" comes back in the same thread, then the + // caller will not have set the onopen handler yet. + setTimeout(function () { + if (self.onopen) { self.onopen(); } }, 10); + } + } catch (e) { + console.error(e.toString()); + } }); + self.__flash.addEventListener("close", function(fe) { + self.readyState = self.__flash.getReadyState(); + + if (self.__messageHandlerID) { + clearInterval(self.__messageHandlerID); + } + try { + if (self.onclose) self.onclose(); + } catch (e) { + console.error(e.toString()); + } + }); + + self.__flash.addEventListener("message", self.__messageHandler); + self.__flash.addEventListener("error", function(fe) { + if (self.__messageHandlerID) { + clearInterval(self.__messageHandlerID); + } try { if (self.onerror) self.onerror(); } catch (e) { @@ -125,6 +145,9 @@ // which causes weird error: // > You are trying to call recursively into the Flash Player which is not allowed. this.readyState = WebSocket.CLOSED; + if (this.__messageHandlerID) { + clearInterval(this.__messageHandlerID); + } if (this.onclose) this.onclose(); };