summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHiroshi Ichikawa <gimite@gmail.com>2010-07-03 13:07:49 +0900
committerHiroshi Ichikawa <gimite@gmail.com>2010-07-03 13:07:49 +0900
commitb674728b29cfdecca399783a35dfd77a3b010c00 (patch)
tree96c266baefeb5cdec658861a05292a16c71a1e93
parent82c6a9d4cb7b358564ef171cf5648ebc05ab2737 (diff)
downloadweb-socket-js-b674728b29cfdecca399783a35dfd77a3b010c00.tar.gz
Enabling polling only for Opera.
Delaying Flash WebSocket object creation instead of delaying onopen. Renaming WebSocket.__swfLocation (and WebSocket__swfLocation) to WEB_SOCKET_SWF_LOCATOIN. Renaming WebSocket.__debug and WebSocket.__disableAutoInitialization to WEB_SOCKET_DEBUG and WEB_SOCKET_DISABLE_AUTO_INITIALIZATION.
-rw-r--r--WebSocketMain.swfbin180513 -> 180134 bytes
-rw-r--r--flash-src/WebSocket.as7
-rw-r--r--flash-src/WebSocketMessageEvent.as30
-rw-r--r--sample.html4
-rwxr-xr-xweb_socket.js193
5 files changed, 103 insertions, 131 deletions
diff --git a/WebSocketMain.swf b/WebSocketMain.swf
index 023eb6f..8716475 100644
--- a/WebSocketMain.swf
+++ b/WebSocketMain.swf
Binary files differ
diff --git a/flash-src/WebSocket.as b/flash-src/WebSocket.as
index c6dad11..6da6472 100644
--- a/flash-src/WebSocket.as
+++ b/flash-src/WebSocket.as
@@ -22,7 +22,7 @@ import com.hurlant.crypto.tls.TLSEngine;
import com.hurlant.crypto.tls.TLSSecurityParameters;
import com.gsolo.encryption.MD5;
-[Event(name="message", type="WebSocketMessageEvent")]
+[Event(name="message", type="flash.events.Event")]
[Event(name="open", type="flash.events.Event")]
[Event(name="close", type="flash.events.Event")]
[Event(name="error", type="flash.events.Event")]
@@ -279,7 +279,7 @@ public class WebSocket extends EventDispatcher {
var data:String = buffer.readUTFBytes(pos - 1);
main.log("received: " + data);
dataQueue.push(encodeURIComponent(data));
- dispatchEvent(new WebSocketMessageEvent("message", data.length.toString()));
+ dispatchEvent(new Event("message"));
removeBufferBefore(pos + 1);
pos = -1;
} else if (pos == 1 && buffer[0] == 0xff && buffer[1] == 0x00) { // closing
@@ -297,8 +297,7 @@ public class WebSocket extends EventDispatcher {
public function readSocketData():Array {
var q:Array = dataQueue;
if (dataQueue.length > 0) {
- // Reset to empty
- dataQueue = [];
+ dataQueue = [];
}
return q;
}
diff --git a/flash-src/WebSocketMessageEvent.as b/flash-src/WebSocketMessageEvent.as
deleted file mode 100644
index a1385a0..0000000
--- a/flash-src/WebSocketMessageEvent.as
+++ /dev/null
@@ -1,30 +0,0 @@
-// Copyright: Hiroshi Ichikawa <http://gimite.net/en/>
-// License: New BSD License
-// Reference: http://dev.w3.org/html5/websockets/
-// Reference: http://tools.ietf.org/html/draft-hixie-thewebsocketprotocol-31
-
-package {
-
-import flash.display.*;
-import flash.events.*;
-import flash.external.*;
-import flash.net.*;
-import flash.system.*;
-import flash.utils.*;
-import mx.core.*;
-import mx.controls.*;
-import mx.events.*;
-import mx.utils.*;
-
-public class WebSocketMessageEvent extends Event {
-
- public var data:String;
-
- public function WebSocketMessageEvent(type:String, data:String) {
- super(type);
- this.data = data;
- }
-
-}
-
-}
diff --git a/sample.html b/sample.html
index ac9ca01..9d2c920 100644
--- a/sample.html
+++ b/sample.html
@@ -14,9 +14,9 @@
<script type="text/javascript">
// Set URL of your WebSocketMain.swf here:
- WebSocket.__swfLocation = "WebSocketMain.swf";
+ WEB_SOCKET_SWF_LOCATION = "WebSocketMain.swf";
// Set this to dump debug message from Flash to console.log:
- WebSocket.__debug = true;
+ WEB_SOCKET_DEBUG = true;
var ws;
diff --git a/web_socket.js b/web_socket.js
index 5b0afc1..271a30d 100755
--- a/web_socket.js
+++ b/web_socket.js
@@ -31,96 +31,77 @@
var self = this;
self.readyState = WebSocket.CONNECTING;
self.bufferedAmount = 0;
- WebSocket.__addTask(function() {
- self.__flash =
- WebSocket.__flash.create(url, protocol, proxyHost || null, proxyPort || 0, headers || null);
-
- self.__messageHandler = function() {
- var i, arr, data;
- arr = self.__flash.readSocketData();
- for (i=0; i < arr.length; i++) {
- data = decodeURIComponent(arr[i]);
- try {
- if (self.onmessage) {
- var e;
- if (window.MessageEvent) {
- e = document.createEvent("MessageEvent");
- e.initMessageEvent("message", false, false, data, null, null, window, null);
- } else { // IE
- e = {data: data};
- }
- self.onmessage(e);
- }
- } catch (e) {
- 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());
- }
+ // Uses setTimeout() to make sure __createFlash() runs after the caller sets ws.onopen etc.
+ // Otherwise, when onopen fires immediately, onopen is called before it is set.
+ setTimeout(function() {
+ WebSocket.__addTask(function() {
+ self.__createFlash(url, protocol, proxyHost, proxyPort, headers);
});
+ }, 1);
+ }
+
+ WebSocket.prototype.__createFlash = function(url, protocol, proxyHost, proxyPort, headers) {
+ var self = this;
+ self.__flash =
+ WebSocket.__flash.create(url, protocol, proxyHost || null, proxyPort || 0, headers || null);
+
+ self.__flash.addEventListener("open", function(fe) {
+ self.readyState = self.__flash.getReadyState();
+
+ if (self.__timer) clearInterval(self.__timer);
+ if (window.opera) {
+ // Workaround for weird behavior of Opera which sometimes drops events.
+ self.__timer = setInterval(function () {
+ self.__handleMessages();
+ }, 500);
+ }
- self.__flash.addEventListener("close", function(fe) {
- self.readyState = self.__flash.getReadyState();
+ try {
+ if (self.onopen) self.onopen();
+ } catch (e) {
+ console.error(e.toString());
+ }
+ });
- if (self.__messageHandlerID) {
- clearInterval(self.__messageHandlerID);
- }
- try {
- if (self.onclose) self.onclose();
- } catch (e) {
- console.error(e.toString());
- }
- });
+ self.__flash.addEventListener("close", function(fe) {
+ self.readyState = self.__flash.getReadyState();
- self.__flash.addEventListener("message", self.__messageHandler);
+ if (self.__timer) clearInterval(self.__timer);
+ try {
+ if (self.onclose) self.onclose();
+ } catch (e) {
+ console.error(e.toString());
+ }
+ });
- self.__flash.addEventListener("error", function(fe) {
- if (self.__messageHandlerID) {
- clearInterval(self.__messageHandlerID);
- }
- try {
- if (self.onerror) self.onerror();
- } catch (e) {
- console.error(e.toString());
- }
- });
+ self.__flash.addEventListener("message", function() {
+ try {
+ self.__handleMessages();
+ } catch (e) {
+ console.error(e.toString());
+ }
+ });
- self.__flash.addEventListener("stateChange", function(fe) {
- try {
- self.readyState = fe.getReadyState();
- self.bufferedAmount = fe.getBufferedAmount();
- } catch (e) {
- console.error(e.toString());
- }
- });
+ self.__flash.addEventListener("error", function(fe) {
+ if (self.__timer) clearInterval(self.__timer);
+ try {
+ if (self.onerror) self.onerror();
+ } catch (e) {
+ console.error(e.toString());
+ }
+ });
- //console.log("[WebSocket] Flash object is ready");
+ self.__flash.addEventListener("stateChange", function(fe) {
+ try {
+ self.readyState = fe.getReadyState();
+ self.bufferedAmount = fe.getBufferedAmount();
+ } catch (e) {
+ console.error(e.toString());
+ }
});
- }
+
+ //console.log("[WebSocket] Flash object is ready");
+ };
WebSocket.prototype.send = function(data) {
this.readyState = this.__flash.getReadyState();
@@ -145,9 +126,7 @@
// 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.__timer) clearInterval(this.__timer);
if (this.onclose) this.onclose();
};
@@ -167,7 +146,7 @@
this.__events[type] = [];
if ('function' == typeof this['on' + type]) {
this.__events[type].defaultHandler = this['on' + type];
- this['on' + type] = WebSocket_FireEvent(this, type);
+ this['on' + type] = this.__createEventHandler(this, type);
}
}
this.__events[type].push(listener);
@@ -216,12 +195,35 @@
}
};
+ WebSocket.prototype.__handleMessages = function() {
+ // Gets data using readSocketData() instead of getting it from event object
+ // of Flash event. This is to make sure to keep message order.
+ // It seems sometimes Flash events don't arrive in the same order as they are sent.
+ var arr = this.__flash.readSocketData();
+ for (var i = 0; i < arr.length; i++) {
+ var data = decodeURIComponent(arr[i]);
+ try {
+ if (this.onmessage) {
+ var e;
+ if (window.MessageEvent) {
+ e = document.createEvent("MessageEvent");
+ e.initMessageEvent("message", false, false, data, null, null, window, null);
+ } else { // IE
+ e = {data: data};
+ }
+ this.onmessage(e);
+ }
+ } catch (e) {
+ console.error(e.toString());
+ }
+ }
+ };
+
/**
- *
* @param {object} object
* @param {string} type
*/
- function WebSocket_FireEvent(object, type) {
+ WebSocket.prototype.__createEventHandler = function(object, type) {
return function(data) {
var event = new WebSocketEvent();
event.initEvent(type, true, true);
@@ -293,11 +295,12 @@
WebSocket.__tasks = [];
WebSocket.__initialize = function() {
- if (WebSocket__swfLocation) {
- WebSocket.__swfLocation = WebSocket__swfLocation;
+ if (WebSocket.__swfLocation) {
+ // For backword compatibility.
+ window.WEB_SOCKET_SWF_LOCATION = WebSocket.__swfLocation;
}
- if (!WebSocket.__swfLocation) {
- console.error("[WebSocket] set WebSocket.__swfLocation to location of WebSocketMain.swf");
+ if (!window.WEB_SOCKET_SWF_LOCATION) {
+ console.error("[WebSocket] set WEB_SOCKET_SWF_LOCATION to location of WebSocketMain.swf");
return;
}
var container = document.createElement("div");
@@ -312,7 +315,7 @@
container.appendChild(holder);
document.body.appendChild(container);
swfobject.embedSWF(
- WebSocket.__swfLocation, "webSocketFlash", "8", "8", "9.0.0",
+ WEB_SOCKET_SWF_LOCATION, "webSocketFlash", "8", "8", "9.0.0",
null, {bridgeName: "webSocket"}, null, null,
function(e) {
if (!e.success) console.error("[WebSocket] swfobject.embedSWF failed");
@@ -323,7 +326,7 @@
//console.log("[WebSocket] FABridge initializad");
WebSocket.__flash = FABridge.webSocket.root();
WebSocket.__flash.setCallerUrl(location.href);
- WebSocket.__flash.setDebug(!!WebSocket.__debug);
+ WebSocket.__flash.setDebug(!!window.WEB_SOCKET_DEBUG);
for (var i = 0; i < WebSocket.__tasks.length; ++i) {
WebSocket.__tasks[i]();
}
@@ -352,7 +355,7 @@
console.error(decodeURIComponent(message));
};
- if (!WebSocket.__disableAutoInitialization) {
+ if (!window.WEB_SOCKET_DISABLE_AUTO_INITIALIZATION) {
if (window.addEventListener) {
window.addEventListener("load", WebSocket.__initialize, false);
} else {