Opera works! Fix message event drops/reorders.
Instead of relying on FABridge AS -> JS event delivery, we just use the events to notify JS of pending data. The message handler then calls the AS readSocketData routine which sends back an array of the pending WebSocket frames. There is still a minor bug somewhere that happens after the first connect where the web-socket-js throws an "INVALID_STATE_ERR: Web Socket connection has not been established". But, Opera is now usable and we should be able to drop the packet sequence numbering and re-ordering code. Another minor issue to better support Opera is to move JS script includes to the <head> of the page instead of after the body.
This commit is contained in:
@@ -48,6 +48,7 @@ public class WebSocket extends EventDispatcher {
|
||||
private var origin:String;
|
||||
private var protocol:String;
|
||||
private var buffer:ByteArray = new ByteArray();
|
||||
private var dataQueue:Array;
|
||||
private var headerState:int = 0;
|
||||
private var readyState:int = CONNECTING;
|
||||
private var bufferedAmount:int = 0;
|
||||
@@ -61,6 +62,7 @@ public class WebSocket extends EventDispatcher {
|
||||
headers:String = null) {
|
||||
this.main = main;
|
||||
initNoiseChars();
|
||||
dataQueue = [];
|
||||
this.url = url;
|
||||
var m:Array = url.match(/^(\w+):\/\/([^\/:]+)(:(\d+))?(\/.*)?$/);
|
||||
if (!m) main.fatal("SYNTAX_ERR: invalid url: " + url);
|
||||
@@ -270,30 +272,10 @@ public class WebSocket extends EventDispatcher {
|
||||
onError("data must start with \\x00");
|
||||
return;
|
||||
}
|
||||
/*
|
||||
var data:String = "", byte:uint;
|
||||
while (buffer.bytesAvailable > 1) {
|
||||
byte = buffer[buffer.position];
|
||||
if (byte === 0x00) {
|
||||
// readUTFBytes mishandles 0x00
|
||||
data = data + "\x00";
|
||||
buffer.position++;
|
||||
} else if (byte === 0xff) {
|
||||
// End of WebSocket frame
|
||||
//ExternalInterface.call("console.log", "[WebSocket] early 0xff found");
|
||||
break;
|
||||
} else if ((byte & 0x80) === 0x00) {
|
||||
// One UTF-8 input byte to one output byte
|
||||
data = data + buffer.readUTFBytes(1);
|
||||
} else {
|
||||
// Assume two UTF-8 input bytes to one output byte
|
||||
data = data + buffer.readUTFBytes(2);
|
||||
}
|
||||
}
|
||||
*/
|
||||
var data:String = buffer.readUTFBytes(pos - 1);
|
||||
main.log("received: " + data);
|
||||
dispatchEvent(new WebSocketMessageEvent("message", encodeURIComponent(data)));
|
||||
dataQueue.push(encodeURIComponent(data));
|
||||
dispatchEvent(new WebSocketMessageEvent("message", data.length.toString()));
|
||||
buffer.readByte();
|
||||
makeBufferCompact();
|
||||
pos = -1;
|
||||
@@ -301,6 +283,15 @@ public class WebSocket extends EventDispatcher {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function readSocketData():Array {
|
||||
var q:Array = dataQueue;
|
||||
if (dataQueue.length > 0) {
|
||||
// Reset to empty
|
||||
dataQueue = [];
|
||||
}
|
||||
return q;
|
||||
}
|
||||
|
||||
private function validateHeader(headerStr:String):Boolean {
|
||||
var lines:Array = headerStr.split(/\r\n/);
|
||||
|
||||
@@ -52,20 +52,24 @@
|
||||
});
|
||||
|
||||
self.__flash.addEventListener("message", function(fe) {
|
||||
var data = decodeURIComponent(fe.getData());
|
||||
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};
|
||||
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);
|
||||
}
|
||||
self.onmessage(e);
|
||||
} catch (e) {
|
||||
console.error(e.toString());
|
||||
}
|
||||
} catch (e) {
|
||||
console.error(e.toString());
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user