summaryrefslogtreecommitdiff
path: root/js/src/Ice/browser/WSTransceiver.js
diff options
context:
space:
mode:
Diffstat (limited to 'js/src/Ice/browser/WSTransceiver.js')
-rw-r--r--js/src/Ice/browser/WSTransceiver.js701
1 files changed, 350 insertions, 351 deletions
diff --git a/js/src/Ice/browser/WSTransceiver.js b/js/src/Ice/browser/WSTransceiver.js
index 9015659d9e1..f310c16dbc3 100644
--- a/js/src/Ice/browser/WSTransceiver.js
+++ b/js/src/Ice/browser/WSTransceiver.js
@@ -7,425 +7,424 @@
//
// **********************************************************************
-(function(global){
- require("Ice/Class");
- require("Ice/Debug");
- require("Ice/ExUtil");
- require("Ice/Network");
- require("Ice/SocketOperation");
- require("Ice/Connection");
- require("Ice/Exception");
- require("Ice/LocalException");
-
- var Ice = global.Ice || {};
-
- var Debug = Ice.Debug;
- var ExUtil = Ice.ExUtil;
- var Network = Ice.Network;
- var SocketOperation = Ice.SocketOperation;
- var Conn = Ice.Connection;
- var LocalException = Ice.LocalException;
- var SocketException = Ice.SocketException;
+var Ice = require("../Ice/ModuleRegistry").Ice;
+Ice.__M.require(module, "Ice",
+ [
+ "../Ice/Class",
+ "../Ice/Debug",
+ "../Ice/ExUtil",
+ "../Ice/Network",
+ "../Ice/SocketOperation",
+ "../Ice/Connection",
+ "../Ice/Exception",
+ "../Ice/LocalException"
+ ]);
- var StateNeedConnect = 0;
- var StateConnectPending = 1;
- var StateConnected = 2;
- var StateClosePending = 3;
- var StateClosed = 4;
+var Debug = Ice.Debug;
+var ExUtil = Ice.ExUtil;
+var Network = Ice.Network;
+var SocketOperation = Ice.SocketOperation;
+var Conn = Ice.Connection;
+var LocalException = Ice.LocalException;
+var SocketException = Ice.SocketException;
- var IsFirefox = navigator.userAgent.indexOf("Firefox") !== -1;
-
- var WSTransceiver = Ice.Class({
- __init__: function(instance)
- {
- var id = instance.initializationData();
- this._traceLevels = instance.traceLevels();
- this._logger = id.logger;
- this._readBuffers = [];
- this._readPosition = 0;
- this._maxSendPacketSize = id.properties.getPropertyAsIntWithDefault("Ice.TCP.SndSize", 512 * 1204);
- },
- setCallbacks: function(connectedCallback, bytesAvailableCallback, bytesWrittenCallback)
- {
- this._connectedCallback = connectedCallback;
- this._bytesAvailableCallback = bytesAvailableCallback;
+var StateNeedConnect = 0;
+var StateConnectPending = 1;
+var StateConnected = 2;
+var StateClosePending = 3;
+var StateClosed = 4;
- var transceiver = this;
- this._bytesWrittenCallback = function()
- {
- if(transceiver._fd)
- {
- if(transceiver._fd.bufferedAmount < 1024 || this._exception)
- {
- bytesWrittenCallback();
- }
- else
- {
- setTimeout(transceiver._bytesWrittenCallback, 50);
- }
- }
- };
- },
- //
- // Returns SocketOperation.None when initialization is complete.
- //
- initialize: function(readBuffer, writeBuffer)
+var IsFirefox = navigator.userAgent.indexOf("Firefox") !== -1;
+
+var WSTransceiver = Ice.Class({
+ __init__: function(instance)
+ {
+ var id = instance.initializationData();
+ this._traceLevels = instance.traceLevels();
+ this._logger = id.logger;
+ this._readBuffers = [];
+ this._readPosition = 0;
+ this._maxSendPacketSize = id.properties.getPropertyAsIntWithDefault("Ice.TCP.SndSize", 512 * 1204);
+ },
+ setCallbacks: function(connectedCallback, bytesAvailableCallback, bytesWrittenCallback)
+ {
+ this._connectedCallback = connectedCallback;
+ this._bytesAvailableCallback = bytesAvailableCallback;
+
+ var transceiver = this;
+ this._bytesWrittenCallback = function()
{
- try
+ if(transceiver._fd)
{
- if(this._exception)
- {
- throw this._exception;
- }
-
- if(this._state === StateNeedConnect)
+ if(transceiver._fd.bufferedAmount < 1024 || this._exception)
{
- this._state = StateConnectPending;
- this._fd = new WebSocket(this._url, "ice.zeroc.com");
- this._fd.binaryType = "arraybuffer";
- var self = this;
- this._fd.onopen = function(e) { self.socketConnected(e); };
- this._fd.onmessage = function(e) { self.socketBytesAvailable(e.data); };
- this._fd.onclose = function(e) { self.socketClosed(e); };
- return SocketOperation.Connect; // Waiting for connect to complete.
+ bytesWrittenCallback();
}
- else if(this._state === StateConnectPending)
+ else
{
- //
- // Socket is connected.
- //
- this._desc = fdToString(this._addr);
- this._state = StateConnected;
+ setTimeout(transceiver._bytesWrittenCallback, 50);
}
}
- catch(err)
+ };
+ },
+ //
+ // Returns SocketOperation.None when initialization is complete.
+ //
+ initialize: function(readBuffer, writeBuffer)
+ {
+ try
+ {
+ if(this._exception)
{
- if(!this._exception)
- {
- this._exception = translateError(this._state, err);
- }
-
- if(this._traceLevels.network >= 2)
- {
- var s = [];
- s.push("failed to establish " + this.type() + " connection\n");
- s.push(fdToString(this._addr));
- this._logger.trace(this._traceLevels.networkCat, s.join(""));
- }
throw this._exception;
}
- Debug.assert(this._state === StateConnected);
- if(this._traceLevels.network >= 1)
+ if(this._state === StateNeedConnect)
{
- this._logger.trace(this._traceLevels.networkCat, this.type() +
- " connection established\n" + this._desc);
+ this._state = StateConnectPending;
+ this._fd = new WebSocket(this._url, "ice.zeroc.com");
+ this._fd.binaryType = "arraybuffer";
+ var self = this;
+ this._fd.onopen = function(e) { self.socketConnected(e); };
+ this._fd.onmessage = function(e) { self.socketBytesAvailable(e.data); };
+ this._fd.onclose = function(e) { self.socketClosed(e); };
+ return SocketOperation.Connect; // Waiting for connect to complete.
}
- return SocketOperation.None;
- },
- register: function()
- {
- //
- // Register the socket data listener.
- //
- this._registered = true;
- if(this._hasBytesAvailable || this._exception)
+ else if(this._state === StateConnectPending)
{
- this._bytesAvailableCallback();
- this._hasBytesAvailable = false;
+ //
+ // Socket is connected.
+ //
+ this._desc = fdToString(this._addr);
+ this._state = StateConnected;
}
- },
- unregister: function()
- {
- //
- // Unregister the socket data listener.
- //
- this._registered = false;
- },
- close: function()
+ }
+ catch(err)
{
- if(this._fd === null)
+ if(!this._exception)
{
- Debug.assert(this._exception); // Websocket creation failed.
- return;
+ this._exception = translateError(this._state, err);
}
- //
- // WORKAROUND: With Firefox, calling close() if the websocket isn't connected
- // yet doesn't close the connection. The server doesn't receive any close frame
- // and the underlying socket isn't closed causing the server to hang on closing
- // the connection until the browser exits.
- //
- // To workaround this problem, we always wait for the socket to be connected
- // or closed before closing the socket.
- //
- if(this._fd.readyState === WebSocket.CONNECTING && IsFirefox)
- {
- this._state = StateClosePending;
- return;
- }
-
- if(this._state == StateConnected && this._traceLevels.network >= 1)
+ if(this._traceLevels.network >= 2)
{
- this._logger.trace(this._traceLevels.networkCat, "closing " + this.type() + " connection\n" +
- this._desc);
+ var s = [];
+ s.push("failed to establish " + this.type() + " connection\n");
+ s.push(fdToString(this._addr));
+ this._logger.trace(this._traceLevels.networkCat, s.join(""));
}
+ throw this._exception;
+ }
- Debug.assert(this._fd !== null);
- try
- {
- this._state = StateClosed;
- this._fd.close();
- }
- catch(ex)
- {
- throw translateError(this._state, ex);
- }
- finally
- {
- this._fd = null;
- }
- },
+ Debug.assert(this._state === StateConnected);
+ if(this._traceLevels.network >= 1)
+ {
+ this._logger.trace(this._traceLevels.networkCat, this.type() +
+ " connection established\n" + this._desc);
+ }
+ return SocketOperation.None;
+ },
+ register: function()
+ {
//
- // Returns true if all of the data was flushed to the kernel buffer.
+ // Register the socket data listener.
//
- write: function(byteBuffer)
+ this._registered = true;
+ if(this._hasBytesAvailable || this._exception)
{
- if(this._exception)
- {
- throw this._exception;
- }
- else if(byteBuffer.remaining === 0)
- {
- return true;
- }
-
- if(this._fd.bufferedAmount > 1024)
- {
- setTimeout(this._bytesWrittenCallback, 50);
- return false;
- }
+ this._bytesAvailableCallback();
+ this._hasBytesAvailable = false;
+ }
+ },
+ unregister: function()
+ {
+ //
+ // Unregister the socket data listener.
+ //
+ this._registered = false;
+ },
+ close: function()
+ {
+ if(this._fd === null)
+ {
+ Debug.assert(this._exception); // Websocket creation failed.
+ return;
+ }
- var packetSize = byteBuffer.remaining;
- Debug.assert(packetSize > 0);
- Debug.assert(this._fd);
-
- if(this._maxSendPacketSize > 0 && packetSize > this._maxSendPacketSize)
- {
- packetSize = this._maxSendPacketSize;
- }
+ //
+ // WORKAROUND: With Firefox, calling close() if the websocket isn't connected
+ // yet doesn't close the connection. The server doesn't receive any close frame
+ // and the underlying socket isn't closed causing the server to hang on closing
+ // the connection until the browser exits.
+ //
+ // To workaround this problem, we always wait for the socket to be connected
+ // or closed before closing the socket.
+ //
+ if(this._fd.readyState === WebSocket.CONNECTING && IsFirefox)
+ {
+ this._state = StateClosePending;
+ return;
+ }
+
+ if(this._state == StateConnected && this._traceLevels.network >= 1)
+ {
+ this._logger.trace(this._traceLevels.networkCat, "closing " + this.type() + " connection\n" +
+ this._desc);
+ }
- while(packetSize > 0)
- {
- var slice = byteBuffer.b.slice(byteBuffer.position, byteBuffer.position + packetSize);
- this._fd.send(slice);
+ Debug.assert(this._fd !== null);
+ try
+ {
+ this._state = StateClosed;
+ this._fd.close();
+ }
+ catch(ex)
+ {
+ throw translateError(this._state, ex);
+ }
+ finally
+ {
+ this._fd = null;
+ }
+ },
+ //
+ // Returns true if all of the data was flushed to the kernel buffer.
+ //
+ write: function(byteBuffer)
+ {
+ if(this._exception)
+ {
+ throw this._exception;
+ }
+ else if(byteBuffer.remaining === 0)
+ {
+ return true;
+ }
- if(this._traceLevels.network >= 3)
- {
- this._logger.trace(this._traceLevels.networkCat, "sent " + packetSize + " of " +
- byteBuffer.remaining + " bytes via " + this.type() + "\n" + this._desc);
- }
- byteBuffer.position = byteBuffer.position + packetSize;
+ if(this._fd.bufferedAmount > 1024)
+ {
+ setTimeout(this._bytesWrittenCallback, 50);
+ return false;
+ }
- if(this._maxSendPacketSize > 0 && byteBuffer.remaining > this._maxSendPacketSize)
- {
- packetSize = this._maxSendPacketSize;
- }
- else
- {
- packetSize = byteBuffer.remaining;
- }
+ var packetSize = byteBuffer.remaining;
+ Debug.assert(packetSize > 0);
+ Debug.assert(this._fd);
+
+ if(this._maxSendPacketSize > 0 && packetSize > this._maxSendPacketSize)
+ {
+ packetSize = this._maxSendPacketSize;
+ }
- if(this._fd.bufferedAmount > 0 && packetSize > 0)
- {
- setTimeout(this._bytesWrittenCallback, 50);
- return false;
- }
- }
- return true;
- },
- read: function(byteBuffer, moreData)
+ while(packetSize > 0)
{
- if(this._exception)
+ var slice = byteBuffer.b.slice(byteBuffer.position, byteBuffer.position + packetSize);
+ this._fd.send(slice);
+
+ if(this._traceLevels.network >= 3)
{
- throw this._exception;
+ this._logger.trace(this._traceLevels.networkCat, "sent " + packetSize + " of " +
+ byteBuffer.remaining + " bytes via " + this.type() + "\n" + this._desc);
}
+ byteBuffer.position = byteBuffer.position + packetSize;
- moreData.value = false;
-
- if(this._readBuffers.length === 0)
+ if(this._maxSendPacketSize > 0 && byteBuffer.remaining > this._maxSendPacketSize)
{
- return false; // No data available.
+ packetSize = this._maxSendPacketSize;
}
-
- var avail = this._readBuffers[0].byteLength - this._readPosition;
- Debug.assert(avail > 0);
- var remaining = byteBuffer.remaining;
-
- while(byteBuffer.remaining > 0)
+ else
{
- if(avail > byteBuffer.remaining)
- {
- avail = byteBuffer.remaining;
- }
-
- new Uint8Array(byteBuffer.b).set(new Uint8Array(this._readBuffers[0], this._readPosition, avail),
- byteBuffer.position);
-
- byteBuffer.position += avail;
- this._readPosition += avail;
- if(this._readPosition === this._readBuffers[0].byteLength)
- {
- //
- // We've exhausted the current read buffer.
- //
- this._readPosition = 0;
- this._readBuffers.shift();
- if(this._readBuffers.length === 0)
- {
- break; // No more data - we're done.
- }
- else
- {
- avail = this._readBuffers[0].byteLength;
- }
- }
+ packetSize = byteBuffer.remaining;
}
- var n = remaining - byteBuffer.remaining;
- if(n > 0 && this._traceLevels.network >= 3)
+ if(this._fd.bufferedAmount > 0 && packetSize > 0)
{
- var msg = "received " + n + " of " + remaining + " bytes via " + this.type() + "\n" + this._desc;
- this._logger.trace(this._traceLevels.networkCat, msg);
+ setTimeout(this._bytesWrittenCallback, 50);
+ return false;
}
+ }
+ return true;
+ },
+ read: function(byteBuffer, moreData)
+ {
+ if(this._exception)
+ {
+ throw this._exception;
+ }
- moreData.value = this._readBuffers.byteLength > 0;
+ moreData.value = false;
- return byteBuffer.remaining === 0;
- },
- type: function()
- {
- return this._secure ? "wss" : "ws";
- },
- getInfo: function()
- {
- Debug.assert(this._fd !== null);
- var info = this.createInfo();
-
- //
- // The WebSocket API doens't provide this info
- //
- info.localAddress = "";
- info.localPort = -1;
- info.remoteAddress = this._addr.host;
- info.remotePort = this._addr.port;
- return info;
- },
- createInfo: function()
- {
- return new Ice.WSConnectionInfo();
- },
- checkSendSize: function(stream, messageSizeMax)
- {
- if(stream.size > messageSizeMax)
- {
- ExUtil.throwMemoryLimitException(stream.size, messageSizeMax);
- }
- },
- toString: function()
+ if(this._readBuffers.length === 0)
{
- return this._desc;
- },
- socketConnected: function(e)
+ return false; // No data available.
+ }
+
+ var avail = this._readBuffers[0].byteLength - this._readPosition;
+ Debug.assert(avail > 0);
+ var remaining = byteBuffer.remaining;
+
+ while(byteBuffer.remaining > 0)
{
- if(this._state == StateClosePending)
+ if(avail > byteBuffer.remaining)
{
- this.close();
- return;
+ avail = byteBuffer.remaining;
}
-
- Debug.assert(this._connectedCallback !== null);
- this._connectedCallback();
- },
- socketBytesAvailable: function(buf)
- {
- Debug.assert(this._bytesAvailableCallback !== null);
- if(buf.byteLength > 0)
+
+ new Uint8Array(byteBuffer.b).set(new Uint8Array(this._readBuffers[0], this._readPosition, avail),
+ byteBuffer.position);
+
+ byteBuffer.position += avail;
+ this._readPosition += avail;
+ if(this._readPosition === this._readBuffers[0].byteLength)
{
- this._readBuffers.push(buf);
- if(this._registered)
+ //
+ // We've exhausted the current read buffer.
+ //
+ this._readPosition = 0;
+ this._readBuffers.shift();
+ if(this._readBuffers.length === 0)
{
- this._bytesAvailableCallback();
+ break; // No more data - we're done.
}
- else if(!this._hasBytesAvailable)
+ else
{
- this._hasBytesAvailable = true;
+ avail = this._readBuffers[0].byteLength;
}
}
- },
- socketClosed: function(err)
+ }
+
+ var n = remaining - byteBuffer.remaining;
+ if(n > 0 && this._traceLevels.network >= 3)
{
- if(this._state == StateClosePending)
- {
- this.close();
- return;
- }
-
- this._exception = translateError(this._state, err);
- if(this._state < StateConnected)
+ var msg = "received " + n + " of " + remaining + " bytes via " + this.type() + "\n" + this._desc;
+ this._logger.trace(this._traceLevels.networkCat, msg);
+ }
+
+ moreData.value = this._readBuffers.byteLength > 0;
+
+ return byteBuffer.remaining === 0;
+ },
+ type: function()
+ {
+ return this._secure ? "wss" : "ws";
+ },
+ getInfo: function()
+ {
+ Debug.assert(this._fd !== null);
+ var info = this.createInfo();
+
+ //
+ // The WebSocket API doens't provide this info
+ //
+ info.localAddress = "";
+ info.localPort = -1;
+ info.remoteAddress = this._addr.host;
+ info.remotePort = this._addr.port;
+ return info;
+ },
+ createInfo: function()
+ {
+ return new Ice.WSConnectionInfo();
+ },
+ checkSendSize: function(stream, messageSizeMax)
+ {
+ if(stream.size > messageSizeMax)
+ {
+ ExUtil.throwMemoryLimitException(stream.size, messageSizeMax);
+ }
+ },
+ toString: function()
+ {
+ return this._desc;
+ },
+ socketConnected: function(e)
+ {
+ if(this._state == StateClosePending)
+ {
+ this.close();
+ return;
+ }
+
+ Debug.assert(this._connectedCallback !== null);
+ this._connectedCallback();
+ },
+ socketBytesAvailable: function(buf)
+ {
+ Debug.assert(this._bytesAvailableCallback !== null);
+ if(buf.byteLength > 0)
+ {
+ this._readBuffers.push(buf);
+ if(this._registered)
{
- this._connectedCallback();
+ this._bytesAvailableCallback();
}
- else if(this._registered)
+ else if(!this._hasBytesAvailable)
{
- this._bytesAvailableCallback();
+ this._hasBytesAvailable = true;
}
- },
- });
-
- function fdToString(address)
- {
- return "local address = <not available>\nremote address = " + address.host + ":" + address.port;
- }
-
- function translateError(state, err)
+ }
+ },
+ socketClosed: function(err)
{
- if(state < StateConnected)
+ if(this._state == StateClosePending)
+ {
+ this.close();
+ return;
+ }
+
+ this._exception = translateError(this._state, err);
+ if(this._state < StateConnected)
{
- return new Ice.ConnectFailedException(err.code, err);
+ this._connectedCallback();
}
- else
+ else if(this._registered)
{
- if(err.code === 1000 || err.code === 1006) // CLOSE_NORMAL | CLOSE_ABNORMAL
- {
- return new Ice.ConnectionLostException();
- }
- return new Ice.SocketException(err.code, err);
+ this._bytesAvailableCallback();
}
+ },
+});
+
+function fdToString(address)
+{
+ return "local address = <not available>\nremote address = " + address.host + ":" + address.port;
+}
+
+function translateError(state, err)
+{
+ if(state < StateConnected)
+ {
+ return new Ice.ConnectFailedException(err.code, err);
}
-
- WSTransceiver.createOutgoing = function(instance, secure, addr, resource)
+ else
{
- var transceiver = new WSTransceiver(instance);
-
- var url = secure ? "wss" : "ws";
- url += "://" + addr.host;
- if(addr.port !== 80)
+ if(err.code === 1000 || err.code === 1006) // CLOSE_NORMAL | CLOSE_ABNORMAL
{
- url += ":" + addr.port;
+ return new Ice.ConnectionLostException();
}
- url += resource ? resource : "/";
- transceiver._url = url;
- transceiver._fd = null;
- transceiver._addr = addr;
- transceiver._desc = "remote address: " + addr.host + ":" + addr.port + " <not connected>";
- transceiver._state = StateNeedConnect;
- transceiver._secure = secure;
- transceiver._exception = null;
-
- return transceiver;
- };
+ return new Ice.SocketException(err.code, err);
+ }
+}
+
+WSTransceiver.createOutgoing = function(instance, secure, addr, resource)
+{
+ var transceiver = new WSTransceiver(instance);
+
+ var url = secure ? "wss" : "ws";
+ url += "://" + addr.host;
+ if(addr.port !== 80)
+ {
+ url += ":" + addr.port;
+ }
+ url += resource ? resource : "/";
+ transceiver._url = url;
+ transceiver._fd = null;
+ transceiver._addr = addr;
+ transceiver._desc = "remote address: " + addr.host + ":" + addr.port + " <not connected>";
+ transceiver._state = StateNeedConnect;
+ transceiver._secure = secure;
+ transceiver._exception = null;
+
+ return transceiver;
+};
- Ice.WSTransceiver = WSTransceiver;
- global.Ice = Ice;
-}(typeof (global) === "undefined" ? window : global));
+Ice.WSTransceiver = WSTransceiver;