Compare commits

...

18 Commits

Author SHA1 Message Date
Guillermo Rauch
f5b2028577 Release 0.6.4 2011-01-05 11:21:37 -08:00
Fabian Jakobs
7f08d8fd59 Don't destroy the connection in _onClose. Destroying
it will prevent the buffers from being flushed and
will result in corrupted responses for the
xhr-polling transport.

According to the node documentation "destroy" is
only necessary in case of a errors.
2011-01-05 13:25:35 +01:00
Mathew Rodley
ffb0574a76 Added try/catch block around JSON.parse and return an empty object literal
if JSON parsing fails.
2010-12-30 13:18:27 +11:00
Guillermo Rauch
e57e27ee43 Added missing .connect() to example 2010-12-24 13:02:35 -08:00
Guillermo Rauch
3c76d732e6 Client updated to 0.6.1 2010-12-23 20:52:27 -08:00
Guillermo Rauch
e058ae5201 Updated history 2010-12-23 20:50:35 -08:00
Guillermo Rauch
715c46de13 Changed polling default duration to 50 seconds 2010-12-23 20:38:20 -08:00
Guillermo Rauch
eb0e1d3d2c might > will
Adjusted to 85 column limit
2010-12-23 20:11:24 -08:00
Guillermo Rauch
1d6687cecc Fixed typo 2010-12-23 20:08:36 -08:00
Guillermo Rauch
f62bae4e8b Updated client 2010-12-23 17:48:04 -08:00
Guillermo Rauch
28535071bb Support for resources that include slashes. Thanks @schamane 2010-12-23 17:10:39 -08:00
Guillermo Rauch
45f1712d57 Lazy loading of transports. Thanks @technoweenie
Fixed README transports list
2010-12-23 16:52:51 -08:00
Guillermo Rauch
3029d0cf2f OpenSSL clarifications (thanks @bmnds) 2010-12-23 16:46:17 -08:00
Guillermo Rauch
5c9fb03c50 Support for HAProxy load balancing (thanks Brian McKelvey)
Backported Parser from 0.7
2010-12-23 16:25:16 -08:00
Guillermo Rauch
39fab0ab9b Fixed HTTP API in example (was outdated). Thanks deedubs 2010-12-23 15:09:55 -08:00
Guillermo Rauch
c958a12c79 0.3 compatibility (thanks Arnout) 2010-12-23 15:08:06 -08:00
Guillermo Rauch
d298113a3e Temporarily reverting to random session id generation 2010-12-23 14:48:41 -08:00
Guillermo Rauch
3c6fc999dc client.broadcast now 300% faster
Cleaned up chat example
Implemented a simpler session id generation mechanism. Math.random is not webscale
2010-11-11 06:19:07 -03:00
21 changed files with 486 additions and 350 deletions

View File

@@ -1,127 +1,158 @@
0.6.4 / 2011-01-05
==================
* Don't destroy the connection in _onClose. Destroying it will prevent the buffers from being flushed and will result in corrupted responses for the xhr-polling transport.
* Added try/catch block around JSON.parse and return an empty object literal if JSON parsing fails.
* Added missing .connect() to example
0.6.3 / 2010-12-23
==================
* Changed polling default duration to 50 seconds
* might > will Adjusted to 85 column limit
* Support for resources that include slashes. Thanks @schamane
* Lazy loading of transports. Thanks @technoweenie Fixed README transports list
* OpenSSL clarifications (thanks @bmnds)
* Support for HAProxy load balancing (thanks Brian McKelvey) Backported Parser from 0.7
* Fixed HTTP API in example (was outdated). Thanks deedubs
* 0.3 compatibility (thanks Arnout)
* `client.broadcast` now 300% faster Cleaned up chat example
* fixed bad pluralization.
* cleaned up grammar, missing punctuation, etc.
* Restored global `netserver` for flashsocket Now supporting `flashPolicyServer` option (thanks Arnout) Tests passing with and without sudo/root user Fixed noDelay/timeout/utf-8 for draft 76 (accidental typo)
* Close the netServer when the main http server closes, this way the event loop does not keep running. NOTE: this is patch for node 0.2.X, this is not required for node 0.3.X
* Fallback to try{}catch handling for node < 0.2.4 , node 0.3.X seems to capture the errors correctly using the error event.
* Added the flash policy server, it's enabled by default but can be turned off if needed. Socket.io will automatically fallback to serving the policy file inline if server is disabled or unable to start up.
* Make sure to only write to open transports (thanks JohnDav)
* _open is still false, so destroy the connection immediately upon websocket error
* Make sure .connection is not null on 'end'
* Proper fix for invalid websocket key
0.6.1 / 2010-11-08
* Restored flash policy server, but with these changes:
- It's contingent on the listener flashPolicyServer option
- It's started by default if socket.io is started with root access
- It correctly closes the netserver upon all the dependent http servers being closed
- The handler for the inline request is still there regardless. This is important in the following circumstances, and has no performance hit
- The port 843 is filtered
- Flash at some point enables us to skip 843 checking altogether
- Tests compatibility
* Fixed connection timeout, noDelay and socket encoding for draft 76 (had been accidentally moved into the `else` block)
* Some stylistic fixes
0.6.0 / 2010-11-01
==================
* Make sure to only write to open transports (thanks JohnDav)
* _open is still false, so destroy the connection immediately upon websocket error
* Make sure to disconnect directly onClose if the client is not handshaked and he can't possibly reconnect
* Make sure to end and destroy connection onDisconnect (for timeouts)
* Added missing .listen() call to example. Fixes #80. Thanks @machee
* Invalid transport test completed
* Initial stab at trying to detect invalid transport responses
* Make sure to provide a default for `log` if no log key was provided (internal)
* Removed unnecessary file extension verification when serving the client
* Removed unnecessary Client check upon connection
* Added support for /socket.io/WebSocketMain.swf
* Added test for /socket.io/WebSocketMain.swf
* Client serving ETag testing
* Added htmlfile transport tests
* Added extra byte to IE iframe bytes padding
* Invalid session id test
* end() before destroy()ing the socket for non-WebSocket or non-valid Upgrade requests
* Added test for non-socket.io requests
* Simplified index.js tests
* Moved listener tests into listener.js
* Make sure to call .end() when listening on connection 'end' event
* Make sure the file descriptor is destroyed on disconnection
* Fix for websocket client tracking test
* Inline (same port) flash socket policy request.
* If the server is not run with root privileges, then the flashsocket
transport will instead listen to all new connections on the main port
for policy requests. Flash policy requests happen to both port 843 and
the destination port:
http://www.lightsphere.com/dev/articles/flash_socket_policy.html
* Make sure to only write to open transports (thanks JohnDav)
* _open is still false, so destroy the connection immediately upon websocket error
* Make sure to disconnect directly onClose if the client is not handshaked and he can't possibly reconnect
* Make sure to end and destroy connection onDisconnect (for timeouts)
* Added missing .listen() call to example. Fixes #80. Thanks @machee
* Invalid transport test completed
* Initial stab at trying to detect invalid transport responses
* Make sure to provide a default for `log` if no log key was provided (internal)
* Removed unnecessary file extension verification when serving the client
* Removed unnecessary Client check upon connection
* Added support for /socket.io/WebSocketMain.swf
* Added test for /socket.io/WebSocketMain.swf
* Client serving ETag testing
* Added htmlfile transport tests
* Added extra byte to IE iframe bytes padding
* Invalid session id test
* end() before destroy()ing the socket for non-WebSocket or non-valid Upgrade requests
* Added test for non-socket.io requests
* Simplified index.js tests
* Moved listener tests into listener.js
* Make sure to call .end() when listening on connection 'end' event
* Make sure the file descriptor is destroyed on disconnection
* Fix for websocket client tracking test
* Inline (same port) flash socket policy request.
* If the server is not run with root privileges, then the flashsocket
transport will instead listen to all new connections on the main port
for policy requests. Flash policy requests happen to both port 843 and
the destination port:
http://www.lightsphere.com/dev/articles/flash_socket_policy.html
* [websocket test] Fix sending message to client upon connecting
* [websocket test] Fix for connection and handshake test
* [client files serving] Leverage end() write() call
* [client serving] Make sure to not do a useless file lookup when file is cached
* Finished json encoding test
* Look for the heartbeat in the decoded message
* Refactored websocket transports tests to match polling/multipart helpers
* Added coverage testing to Makefile
* Added heartbeat test to multipart
* Added buffered messages test for multipart
* Added assertions for `connected` property for all the tests
* Multipart clients tracking test
* Multipart client>server message sending test
* Make sure to only close the client stream when the roundtrip is complete
* Multipart connection and handshake tests:
- Implemented HTTP client on top of net.Stream with multipart boundary parsing for testing
- Test for connection / server>client message sending
* Removed unnecessary check for this.connection (since we now access the socket through req.connection for all transports)
* Test for `duration` parameter
* Added `make example` to Makefile
* Added clients tracking test for long polling
* Added message buffering test for long polling
* Improve this.request/this.response/this.connection
* Add 'end' listener onConnect, applies to all transports
* Improved error handling onConnect
* Remove legacy `flush` calls
* Removed unnecessary closeTimeout clearing in jsonp polling
* Make sure to close on disconnect if _open = true
* Clear disconnection timeout on disconnection (double check)
* Make sure to clear closeTimeout for polling transports on close.
* Replaced empty with null in log option
* Comma first style for client serving tests
* Long polling integration tests
* Test for heartbeat message
* Added heartbeat timeout test
* Support for listener#log false
* Corrected onConnect signature to support a request and a socket, or a request and a response.
* Removed error checking for non-upgradeable sockets, since they'll be destroyed, and error handling is done onConnect
* Added tests for websocket client tracking
* Added tests for websocket message buffering
* Make sure disconnect timeout is cleared on websocket re-connect
* Updated the flash socket with error detection, and readystate detection.
* This is needed because when a error occures we close down the connection,
* and the stream will become unwriteable.
* Also changed to a single write instead of multiple writes.
* Moved error handling to onConnect to avoid messing with the http.Server global error handlers
* Do special error handling for websocket
* Clearing heartbeat interval upon closing the connection
* Added error listeners, if theses errors are not correcly caught, they will leak memory.
* This caused http://speedo.no.de/ to go up from 1mb per connection after a ECONNECTRESET message
* Added encode=UTF-8 in jsonp-polling.js and xhr-polling.js since UTF-8 is the default encoding for http.ServerResponse.write
* Replaced string.length with Buffer.byteLength in jsonp-polling.js, listener.js and xhr-polling.js because content-length header requires number of bytes and not the number of symbols in string
* Fix COR headers/requests for different ports on Safari.
* Clearing the references to request, response and connection upon disconnect.
* Every require is blocking and requiring the sys module over and over and over again just makes no sense + it hurt performance.. Not to mention.. that it's already included.
* Socket.IO-node now serves the client out of the box for easier implementation
* Memory caching and ETag support for static files
* Tests
* Simplified demo even further thanks to new static file serving
* Failing to pass an origin header would throw an exception and crash the server. Added some handling.
* .connected renamed to ._open, and adopted proper `connected` (fixes #41)
* example/client updated to latest socket.io client
* Better checking of WebSocket connections
* Better handling of SSL location (thanks @jdub)
* Fix for cross-domain websocket (fixes #42)
* Removed clients/clientsIndex and only using the index (fixes #28)
* Fixed WebSocket location header for ws/wss (Thanks @jdub, Fixes #40)
* Cross domain issues with xhr-polling addressed. Thanks Niko Kaiser (@nicokaiser)
* Added origin verification for incoming data.
* Make sure pathname is set (thanks steadicat & swarmation team)
* Fix for accessing routes that being with the namespace but are not a connection attempt. Thanks @steadicat from swarmation
* JSONP-polling support
* Graceful closing of connection for invalid websocket clients
* Make it possible to just require 'socket.io'
* Make sure to abort the connect() method upon bad upgrade / origin verification
* Support for automatic JSON encoding/decoding
* Simplified chat example to take advantage of JSON encoding/decoding
* Removed fs sync call from example
* Better `how to use`
* Make sure to send content-type text/plain to `ok` POST responses
* [websocket test] Fix sending message to client upon connecting
* [websocket test] Fix for connection and handshake test
* [client files serving] Leverage end() write() call
* [client serving] Make sure to not do a useless file lookup when file is cached
* Finished json encoding test
* Look for the heartbeat in the decoded message
* Refactored websocket transports tests to match polling/multipart helpers
* Added coverage testing to Makefile
* Added heartbeat test to multipart
* Added buffered messages test for multipart
* Added assertions for `connected` property for all the tests
* Multipart clients tracking test
* Multipart client>server message sending test
* Make sure to only close the client stream when the roundtrip is complete
* Multipart connection and handshake tests:
- Implemented HTTP client on top of net.Stream with multipart boundary parsing for testing
- Test for connection / server>client message sending
* Removed unnecessary check for this.connection (since we now access the socket through req.connection for all transports)
* Test for `duration` parameter
* Added `make example` to Makefile
* Added clients tracking test for long polling
* Added message buffering test for long polling
* Improve this.request/this.response/this.connection
* Add 'end' listener onConnect, applies to all transports
* Improved error handling onConnect
* Remove legacy `flush` calls
* Removed unnecessary closeTimeout clearing in jsonp polling
* Make sure to close on disconnect if _open = true
* Clear disconnection timeout on disconnection (double check)
* Make sure to clear closeTimeout for polling transports on close.
* Replaced empty with null in log option
* Comma first style for client serving tests
* Long polling integration tests
* Test for heartbeat message
* Added heartbeat timeout test
* Support for listener#log false
* Corrected onConnect signature to support a request and a socket, or a request and a response.
* Removed error checking for non-upgradeable sockets, since they'll be destroyed, and error handling is done onConnect
* Added tests for websocket client tracking
* Added tests for websocket message buffering
* Make sure disconnect timeout is cleared on websocket re-connect
* Updated the flash socket with error detection, and readystate detection.
* This is needed because when a error occures we close down the connection,
* and the stream will become unwriteable.
* Also changed to a single write instead of multiple writes.
* Moved error handling to onConnect to avoid messing with the http.Server global error handlers
* Do special error handling for websocket
* Clearing heartbeat interval upon closing the connection
* Added error listeners, if theses errors are not correcly caught, they will leak memory.
* This caused http://speedo.no.de/ to go up from 1mb per connection after a ECONNECTRESET message
* Added encode=UTF-8 in jsonp-polling.js and xhr-polling.js since UTF-8 is the default encoding for http.ServerResponse.write
* Replaced string.length with Buffer.byteLength in jsonp-polling.js, listener.js and xhr-polling.js because content-length header requires number of bytes and not the number of symbols in string
* Fix COR headers/requests for different ports on Safari.
* Clearing the references to request, response and connection upon disconnect.
* Every require is blocking and requiring the sys module over and over and over again just makes no sense + it hurt performance.. Not to mention.. that it's already included.
* Socket.IO-node now serves the client out of the box for easier implementation
* Memory caching and ETag support for static files
* Tests
* Simplified demo even further thanks to new static file serving
* Failing to pass an origin header would throw an exception and crash the server. Added some handling.
* .connected renamed to ._open, and adopted proper `connected` (fixes #41)
* example/client updated to latest socket.io client
* Better checking of WebSocket connections
* Better handling of SSL location (thanks @jdub)
* Fix for cross-domain websocket (fixes #42)
* Removed clients/clientsIndex and only using the index (fixes #28)
* Fixed WebSocket location header for ws/wss (Thanks @jdub, Fixes #40)
* Cross domain issues with xhr-polling addressed. Thanks Niko Kaiser (@nicokaiser)
* Added origin verification for incoming data.
* Make sure pathname is set (thanks steadicat & swarmation team)
* Fix for accessing routes that being with the namespace but are not a connection attempt. Thanks @steadicat from swarmation
* JSONP-polling support
* Graceful closing of connection for invalid websocket clients
* Make it possible to just require 'socket.io'
* Make sure to abort the connect() method upon bad upgrade / origin verification
* Support for automatic JSON encoding/decoding
* Simplified chat example to take advantage of JSON encoding/decoding
* Removed fs sync call from example
* Better `how to use`
* Make sure to send content-type text/plain to `ok` POST responses
0.6.1 / 2010-11-08
* Restored flash policy server, but with these changes:
- It's contingent on the listener flashPolicyServer option
- It's started by default if socket.io is started with root access
- It correctly closes the netserver upon all the dependent http servers being closed
- The handler for the inline request is still there regardless. This is important in the following circumstances, and has no performance hit
- The port 843 is filtered
- Flash at some point enables us to skip 843 checking altogether
- Tests compatibility
* Fixed connection timeout, noDelay and socket encoding for draft 76 (had been accidentally moved into the `else` block)
* Some stylistic fixes

View File

@@ -12,7 +12,8 @@ The `Socket.IO` server provides seamless support for a variety of transports int
## Requirements
- Node v0.1.103+
- Node v0.1.103+ with `crypto` module support (make sure you have OpenSSL
headers when installing Node to get it)
- The [Socket.IO client](http://github.com/LearnBoost/Socket.IO), to connect from the browser
## How to use
@@ -38,9 +39,8 @@ On the server:
server = http.createServer(function(req, res){
// your normal server code
res.writeHeader(200, {'Content-Type': 'text/html'});
res.writeBody('<h1>Hello world</h1>');
res.finish();
res.writeHead(200, {'Content-Type': 'text/html'});
res.end('<h1>Hello world</h1>');
});
server.listen(80);
@@ -59,6 +59,7 @@ On the client:
<script src="/socket.io/socket.io.js"></script>
<script>
var socket = new io.Socket();
socket.connect();
socket.on('connect', function(){ … })
socket.on('message', function(){ … })
socket.on('disconnect', function(){ … })
@@ -119,7 +120,8 @@ Options:
- *transports*
['websocket', 'server-events', 'flashsocket', 'htmlfile', 'xhr-multipart', 'xhr-polling']
['websocket', 'flashsocket', 'htmlfile', 'xhr-multipart', 'xhr-polling',
'jsonp-polling']
A list of the accepted transports.
@@ -224,4 +226,4 @@ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

View File

@@ -58,4 +58,4 @@
</style>
</body>
</html>
</html>

View File

@@ -1,64 +1,63 @@
var http = require('http'),
url = require('url'),
fs = require('fs'),
io = require('../'),
sys = require('sys'),
/**
* Important note: this application is not suitable for benchmarks!
*/
var http = require('http')
, url = require('url')
, fs = require('fs')
, io = require('../')
, sys = require(process.binding('natives').util ? 'util' : 'sys')
, server;
server = http.createServer(function(req, res){
// your normal server code
var path = url.parse(req.url).pathname;
switch (path){
case '/':
res.writeHead(200, {'Content-Type': 'text/html'});
res.write('<h1>Welcome. Try the <a href="/chat.html">chat</a> example.</h1>');
res.end();
break;
case '/json.js':
case '/chat.html':
fs.readFile(__dirname + path, function(err, data){
if (err) return send404(res);
res.writeHead(200, {'Content-Type': path == 'json.js' ? 'text/javascript' : 'text/html'})
res.write(data, 'utf8');
res.end();
});
break;
default: send404(res);
}
// your normal server code
var path = url.parse(req.url).pathname;
switch (path){
case '/':
res.writeHead(200, {'Content-Type': 'text/html'});
res.write('<h1>Welcome. Try the <a href="/chat.html">chat</a> example.</h1>');
res.end();
break;
case '/json.js':
case '/chat.html':
fs.readFile(__dirname + path, function(err, data){
if (err) return send404(res);
res.writeHead(200, {'Content-Type': path == 'json.js' ? 'text/javascript' : 'text/html'})
res.write(data, 'utf8');
res.end();
});
break;
default: send404(res);
}
}),
send404 = function(res){
res.writeHead(404);
res.write('404');
res.end();
res.writeHead(404);
res.write('404');
res.end();
};
server.listen(8080, {
transportOptions: {
'xhr-polling': {
closeTimeout: 1000 * 60 * 5
}
}
});
server.listen(8080);
// socket.io, I choose you
// simplest chat application evar
var io = io.listen(server),
buffer = [];
var io = io.listen(server)
, buffer = [];
io.on('connection', function(client){
client.send({ buffer: buffer });
client.broadcast({ announcement: client.sessionId + ' connected' });
client.send({ buffer: buffer });
client.broadcast({ announcement: client.sessionId + ' connected' });
client.on('message', function(message){
var msg = { message: [client.sessionId, message] };
buffer.push(msg);
if (buffer.length > 15) buffer.shift();
client.broadcast(msg);
});
client.on('message', function(message){
var msg = { message: [client.sessionId, message] };
buffer.push(msg);
if (buffer.length > 15) buffer.shift();
client.broadcast(msg);
});
client.on('disconnect', function(){
client.broadcast({ announcement: client.sessionId + ' disconnected' });
});
});
client.on('disconnect', function(){
client.broadcast({ announcement: client.sessionId + ' disconnected' });
});
});

View File

@@ -4,7 +4,8 @@ var urlparse = require('url').parse
, options = require('./utils').options
, encode = require('./utils').encode
, decode = require('./utils').decode
, merge = require('./utils').merge;
, merge = require('./utils').merge
, util = require(process.binding('natives').util ? 'util' : 'sys');
var Client = module.exports = function(listener, req, res, options, head){
process.EventEmitter.call(this);
@@ -22,7 +23,7 @@ var Client = module.exports = function(listener, req, res, options, head){
this._onConnect(req, res);
};
require('sys').inherits(Client, process.EventEmitter);
util.inherits(Client, process.EventEmitter);
Client.prototype.send = function(message){
if (!this._open || !(this.connection.readyState === 'open' || this.connection.readyState === 'writeOnly')){
@@ -47,7 +48,11 @@ Client.prototype._onMessage = function(data){
case '~h~':
return this._onHeartbeat(messages[i].substr(3));
case '~j~':
messages[i] = JSON.parse(messages[i].substr(3));
try {
messages[i] = JSON.parse(messages[i].substr(3));
} catch(e) {
messages[i] = {};
}
break;
}
this.emit('message', messages[i]);
@@ -126,7 +131,6 @@ Client.prototype._onClose = function(skipDisconnect){
this._open = false;
if (this.connection){
this.connection.end();
this.connection.destroy();
this.connection = null;
}
this.request = null;
@@ -160,7 +164,6 @@ Client.prototype._queue = function(message){
};
Client.prototype._generateSessionId = function(){
if (this.sessionId) return this.listener.options.log('This client already has a session id');
this.sessionId = Math.random().toString().substr(2);
return this;
};
@@ -181,4 +184,4 @@ Client.prototype._verifyOrigin = function(origin){
return false;
};
for (var i in options) Client.prototype[i] = options[i];
for (var i in options) Client.prototype[i] = options[i];

View File

@@ -1,17 +1,10 @@
var url = require('url')
, sys = require('sys')
, util = require(process.binding('natives').util ? 'util' : 'sys')
, fs = require('fs')
, options = require('./utils').options
, Client = require('./client')
, clientVersion = require('./../../support/socket.io-client/lib/io').io.version
, transports = {
'flashsocket': require('./transports/flashsocket')
, 'htmlfile': require('./transports/htmlfile')
, 'websocket': require('./transports/websocket')
, 'xhr-multipart': require('./transports/xhr-multipart')
, 'xhr-polling': require('./transports/xhr-polling')
, 'jsonp-polling': require('./transports/jsonp-polling')
};
, transports = {};
var Listener = module.exports = function(server, options){
process.EventEmitter.call(this);
@@ -21,14 +14,16 @@ var Listener = module.exports = function(server, options){
origins: '*:*',
resource: 'socket.io',
flashPolicyServer: true,
transports: ['websocket', 'flashsocket', 'htmlfile', 'xhr-multipart', 'xhr-polling', 'jsonp-polling'],
transports: ['websocket', 'flashsocket', 'htmlfile', 'xhr-multipart',
'xhr-polling', 'jsonp-polling'],
transportOptions: {},
log: sys.log
log: util.log
}, options);
if (!this.options.log) this.options.log = function(){};
this.clients = this.clientsIndex = {};
this._clientCount = 0;
this._clientFiles = {};
var listeners = this.server.listeners('request');
@@ -48,18 +43,22 @@ var Listener = module.exports = function(server, options){
}
});
for (var i in transports)
if ('init' in transports[i]) transports[i].init(this);
this.options.transports.forEach(function(name) {
if (!(name in transports))
transports[name] = require('./transports/' + name);
if ('init' in transports[name]) transports[name].init(self);
});
this.options.log('socket.io ready - accepting connections');
};
sys.inherits(Listener, process.EventEmitter);
util.inherits(Listener, process.EventEmitter);
for (var i in options) Listener.prototype[i] = options[i];
Listener.prototype.broadcast = function(message, except){
for (var i = 0, k = Object.keys(this.clients), l = k.length; i < l; i++){
if (this.clients[k[i]] && (!except || [].concat(except).indexOf(this.clients[k[i]].sessionId) == -1)){
if (!except || ((typeof except == 'number' || typeof except == 'string') && k[i] != except)
|| (Array.isArray(except) && except.indexOf(k[i]) == -1)){
this.clients[k[i]].send(message);
}
}
@@ -69,20 +68,20 @@ Listener.prototype.broadcast = function(message, except){
Listener.prototype.check = function(req, res, httpUpgrade, head){
var path = url.parse(req.url).pathname, parts, cn;
if (path && path.indexOf('/' + this.options.resource) === 0){
parts = path.substr(1).split('/');
if (this._serveClient(parts.slice(1).join('/'), req, res)) return true;
if (!(parts[1] in transports)) return false;
if (parts[2]){
cn = this.clients[parts[2]];
parts = path.substr(2 + this.options.resource.length).split('/');
if (this._serveClient(parts.join('/'), req, res)) return true;
if (!(parts[0] in transports)) return false;
if (parts[1]){
cn = this.clients[parts[1]];
if (cn){
cn._onConnect(req, res);
} else {
req.connection.end();
req.connection.destroy();
this.options.log('Couldnt find client with session id "' + parts[2] + '"');
this.options.log('Couldnt find client with session id "' + parts[1] + '"');
}
} else {
this._onConnection(parts[1], req, res, httpUpgrade, head);
this._onConnection(parts[0], req, res, httpUpgrade, head);
}
return true;
}
@@ -164,4 +163,4 @@ Listener.prototype._onClientDisconnect = function(client){
Listener.prototype._onConnection = function(transport, req, res, httpUpgrade, head){
this.options.log('Initializing client with transport "'+ transport +'"');
new transports[transport](this, req, res, this.options.transportOptions[transport], head);
};
};

View File

@@ -1,4 +1,5 @@
var net = require('net')
, util = require(process.binding('natives').util ? 'util' : 'sys')
, WebSocket = require('./websocket')
, listeners = []
, netserver;
@@ -7,7 +8,7 @@ var Flashsocket = module.exports = function(){
WebSocket.apply(this, arguments);
};
require('sys').inherits(Flashsocket, WebSocket);
util.inherits(Flashsocket, WebSocket);
Flashsocket.httpUpgrade = true;
@@ -41,9 +42,10 @@ Flashsocket.init = function(listener){
netserver.listen(843);
} catch(e){
if (e.errno == 13)
listener.options.log('Your node instance does not have root privileges. This means that the flash XML'
+ ' policy file will be served inline instead of on port 843. This might slow down'
+ ' initial connections slightly.');
listener.options.log('Your node instance does not have root privileges.'
+ 'This means that the flash XML policy file will be '
+ 'served inline instead of on port 843. This will slow '
+ 'down initial connections slightly.');
netserver = null;
}
}
@@ -82,4 +84,4 @@ function policy(listeners) {
xml += '</cross-domain-policy>\n';
return xml;
};
};

View File

@@ -1,11 +1,12 @@
var Client = require('../client')
, util = require(process.binding('natives').util ? 'util' : 'sys')
, qs = require('querystring');
var HTMLFile = module.exports = function(){
Client.apply(this, arguments);
};
require('sys').inherits(HTMLFile, Client);
util.inherits(HTMLFile, Client);
HTMLFile.prototype._onConnect = function(req, res){
var self = this, body = '';
@@ -43,4 +44,4 @@ HTMLFile.prototype._onConnect = function(req, res){
HTMLFile.prototype._write = function(message){
if (this._open)
this.response.write('<script>parent.s._('+ JSON.stringify(message) +', document);</script>'); //json for escaping
};
};

View File

@@ -1,10 +1,11 @@
var XHRPolling = require('./xhr-polling');
var XHRPolling = require('./xhr-polling')
, util = require(process.binding('natives').util ? 'util' : 'sys');
JSONPPolling = module.exports = function(){
XHRPolling.apply(this, arguments);
};
require('sys').inherits(JSONPPolling, XHRPolling);
util.inherits(JSONPPolling, XHRPolling);
JSONPPolling.prototype.getOptions = function(){
return {
@@ -31,4 +32,4 @@ JSONPPolling.prototype._write = function(message){
this.response.end();
this._onClose();
}
};
};

View File

@@ -1,22 +1,31 @@
var Client = require('../client')
, Stream = require('net').Stream
, EventEmitter = require('events').EventEmitter
, url = require('url')
, util = require(process.binding('natives').util ? 'util' : 'sys')
, crypto = require('crypto');
WebSocket = module.exports = function(){
Client.apply(this, arguments);
};
require('sys').inherits(WebSocket, Client);
util.inherits(WebSocket, Client);
WebSocket.prototype._onConnect = function(req, socket){
var self = this
, headers = [];
if (!req.connection.setTimeout){
req.connection.end();
return false;
}
this.parser = new Parser();
this.parser.on('data', self._onMessage.bind(this));
this.parser.on('error', self._onClose.bind(this));
Client.prototype._onConnect.call(this, req);
this.data = '';
if (this.request.headers.upgrade !== 'WebSocket' || !this._verifyOrigin(this.request.headers.origin)){
this.listener.options.log('WebSocket connection invalid or Origin not verified');
this._onClose();
@@ -26,8 +35,25 @@ WebSocket.prototype._onConnect = function(req, socket){
var origin = this.request.headers.origin,
location = (origin && origin.substr(0, 5) == 'https' ? 'wss' : 'ws')
+ '://' + this.request.headers.host + this.request.url;
this.waitingForNonce = false;
if ('sec-websocket-key1' in this.request.headers){
/* We need to send the 101 response immediately when using Draft 76 with
a load balancing proxy, such as HAProxy. In order to protect an
unsuspecting non-websocket HTTP server, HAProxy will not send the
8-byte nonce through the connection until the Upgrade: WebSocket
request has been confirmed by the WebSocket server by a 101 response
indicating that the server can handle the upgraded protocol. We
therefore must send the 101 response immediately, and then wait for
the nonce to be forwarded to us afterward in order to finish the
Draft 76 handshake.
*/
// If we don't have the nonce yet, wait for it.
if (!(this.upgradeHead && this.upgradeHead.length >= 8)) {
this.waitingForNonce = true;
}
headers = [
'HTTP/1.1 101 WebSocket Protocol Handshake',
'Upgrade: WebSocket',
@@ -48,39 +74,50 @@ WebSocket.prototype._onConnect = function(req, socket){
'WebSocket-Location: ' + location
];
try {
this.connection.write(headers.concat('', '').join('\r\n'));
} catch(e){
this._onClose();
}
}
try {
this.connection.write(headers.concat('', '').join('\r\n'));
} catch(e){
this._onClose();
}
this.connection.setTimeout(0);
this.connection.setNoDelay(true);
this.connection.setEncoding('utf-8');
if (this.waitingForNonce) {
// Since we will be receiving the binary nonce through the normal HTTP
// data event, set the connection to 'binary' temporarily
this.connection.setEncoding('binary');
this._headers = headers;
}
else {
if (this._proveReception(headers)) this._payload();
}
this.buffer = "";
this.connection.addListener('data', function(data){
self._handle(data);
self.buffer += data;
if (self.waitingForNonce) {
if (self.buffer.length < 8) { return; }
// Restore the connection to utf8 encoding after receiving the nonce
self.connection.setEncoding('utf8');
self.waitingForNonce = false;
// Stuff the nonce into the location where it's expected to be
self.upgradeHead = self.buffer.substr(0,8);
self.buffer = self.buffer.substr(8);
if (self.buffer.length > 0) {
self.parser.add(self.buffer);
}
if (self._proveReception(self._headers)) { self._payload(); }
return;
}
self.parser.add(data);
});
if (this._proveReception(headers)) this._payload();
};
WebSocket.prototype._handle = function(data){
var chunk, chunks, chunk_count;
this.data += data;
chunks = this.data.split('\ufffd');
chunk_count = chunks.length - 1;
for (var i = 0; i < chunk_count; i++){
chunk = chunks[i];
if (chunk[0] !== '\u0000'){
this.listener.options.log('Data incorrectly framed by UA. Dropping connection');
this._onClose();
return false;
}
this._onMessage(chunk.slice(1));
}
this.data = chunks[chunks.length - 1];
};
// http://www.whatwg.org/specs/web-apps/current-work/complete/network.html#opening-handshake
@@ -114,7 +151,7 @@ WebSocket.prototype._proveReception = function(headers){
md5.update(this.upgradeHead.toString('binary'));
try {
this.connection.write(headers.concat('', '').join('\r\n') + md5.digest('binary'), 'binary');
this.connection.write(md5.digest('binary'), 'binary');
} catch(e){
this._onClose();
}
@@ -133,4 +170,41 @@ WebSocket.prototype._write = function(message){
}
};
WebSocket.httpUpgrade = true;
WebSocket.httpUpgrade = true;
function Parser(){
this.buffer = '';
this.i = 0;
};
Parser.prototype.__proto__ = EventEmitter.prototype;
Parser.prototype.add = function(data){
this.buffer += data;
this.parse();
};
Parser.prototype.parse = function(){
for (var i = this.i, chr, l = this.buffer.length; i < l; i++){
chr = this.buffer[i];
if (i === 0){
if (chr != '\u0000')
this.error('Bad framing. Expected null byte as first frame');
else
continue;
}
if (chr == '\ufffd'){
this.emit('data', this.buffer.substr(1, this.buffer.length - 2));
this.buffer = this.buffer.substr(i + 1);
this.i = 0;
return this.parse();
}
}
};
Parser.prototype.error = function(reason){
this.buffer = '';
this.i = 0;
this.emit('error', reason);
return this;
};

View File

@@ -1,11 +1,12 @@
var Client = require('../client')
, util = require(process.binding('natives').util ? 'util' : 'sys')
, qs = require('querystring');
var Multipart = module.exports = function(){
Client.apply(this, arguments);
};
require('sys').inherits(Multipart, Client);
util.inherits(Multipart, Client);
Multipart.prototype._onConnect = function(req, res){
var self = this, body = '', headers = {};
@@ -61,4 +62,4 @@ Multipart.prototype._write = function(message){
this.response.write(message + "\n");
this.response.write("--socketio\n");
}
};
};

View File

@@ -1,22 +1,24 @@
var Client = require('../client')
, util = require(process.binding('natives').util ? 'util' : 'sys')
, qs = require('querystring');
var Polling = module.exports = function(){
Client.apply(this, arguments);
};
require('sys').inherits(Polling, Client);
util.inherits(Polling, Client);
Polling.prototype.getOptions = function(){
return {
timeout: null, // no heartbeats
closeTimeout: 8000,
duration: 20000
duration: 50000
};
};
Polling.prototype._onConnect = function(req, res){
var self = this, body = '';
switch (req.method){
case 'GET':
Client.prototype._onConnect.apply(this, [req, res]);
@@ -74,4 +76,4 @@ Polling.prototype._write = function(message){
this.response.end();
this._onClose();
}
};
};

View File

@@ -1,6 +1,6 @@
{ "name" : "socket.io"
, "description" : "The cross-browser WebSocket"
, "version" : "0.6.1"
, "version" : "0.6.4"
, "author" : "LearnBoost"
, "licenses" :
[ { "type" : "MIT"

View File

@@ -7,12 +7,12 @@
*/
this.io = {
version: '0.6',
version: '0.6.1',
setPath: function(path){
if (window.console && console.error) console.error('io.setPath will be removed. Please set the variable WEB_SOCKET_SWF_LOCATION pointing to WebSocketMain.swf');
this.path = /\/$/.test(path) ? path : path + '/';
WEB_SOCKET_SWF_LOCATION = path + 'lib/vendor/web-socket-js/WebSocketMain.swf';
WEB_SOCKET_SWF_LOCATION = path + 'lib/vendor/web-socket-js/WebSocketMain.swf';
}
};
@@ -20,5 +20,6 @@ if ('jQuery' in this) jQuery.io = this.io;
if (typeof window != 'undefined'){
// WEB_SOCKET_SWF_LOCATION = (document.location.protocol == 'https:' ? 'https:' : 'http:') + '//cdn.socket.io/' + this.io.version + '/WebSocketMain.swf';
WEB_SOCKET_SWF_LOCATION = '/socket.io/lib/vendor/web-socket-js/WebSocketMain.swf';
}
if (typeof WEB_SOCKET_SWF_LOCATION === 'undefined')
WEB_SOCKET_SWF_LOCATION = '/socket.io/lib/vendor/web-socket-js/WebSocketMain.swf';
}

View File

@@ -62,7 +62,7 @@
this.transport.connect();
if (this.options.connectTimeout){
var self = this;
setTimeout(function(){
this.connectTimeoutTimer = setTimeout(function(){
if (!self.connected){
self.disconnect();
if (self.options.tryTransportsOnConnectTimeout && !self._rememberedTransport){
@@ -89,6 +89,7 @@
};
Socket.prototype.disconnect = function(){
if (this.connectTimeoutTimer) clearTimeout(this.connectTimeoutTimer);
this.transport.disconnect();
return this;
};
@@ -99,14 +100,15 @@
return this;
};
Socket.prototype.fire = function(name, args){
if (name in this._events){
for (var i = 0, ii = this._events[name].length; i < ii; i++)
this._events[name][i].apply(this, args === undefined ? [] : args);
}
return this;
};
Socket.prototype.emit = function(name, args){
if (name in this._events){
var events = this._events[name].concat();
for (var i = 0, ii = events.length; i < ii; i++)
events[i].apply(this, args === undefined ? [] : args);
}
return this;
};
Socket.prototype.removeEvent = function(name, fn){
if (name in this._events){
for (var a = 0, l = this._events[name].length; a < l; a++)
@@ -137,11 +139,11 @@
this.connecting = false;
this._doQueue();
if (this.options.rememberTransport) this.options.document.cookie = 'socketio=' + encodeURIComponent(this.transport.type);
this.fire('connect');
this.emit('connect');
};
Socket.prototype._onMessage = function(data){
this.fire('message', [data]);
this.emit('message', [data]);
};
Socket.prototype._onDisconnect = function(){
@@ -149,9 +151,11 @@
this.connected = false;
this.connecting = false;
this._queueStack = [];
if (wasConnected) this.fire('disconnect');
if (wasConnected) this.emit('disconnect');
};
Socket.prototype.fire = Socket.prototype.emit;
Socket.prototype.addListener = Socket.prototype.addEvent = Socket.prototype.addEventListener = Socket.prototype.on;
})();
})();

View File

@@ -21,6 +21,7 @@
this.socket = new WebSocket(this._prepareUrl());
this.socket.onmessage = function(ev){ self._onData(ev.data); };
this.socket.onclose = function(ev){ self._onClose(); };
this.socket.onerror = function(e){ self._onError(e); };
return this;
};
@@ -38,6 +39,10 @@
this._onDisconnect();
return this;
};
WS.prototype._onError = function(e){
this.base.emit('error', [e]);
};
WS.prototype._prepareUrl = function(){
return (this.base.options.secure ? 'wss' : 'ws')
@@ -57,4 +62,4 @@
return true;
};
})();
})();

View File

@@ -22,7 +22,7 @@
this._xhr.onreadystatechange = function(){
if (self._xhr.readyState == 3) self._onData(self._xhr.responseText);
};
this._xhr.send();
this._xhr.send(null);
};
XHRMultipart.check = function(){
@@ -33,4 +33,4 @@
return true;
};
})();
})();

View File

@@ -34,27 +34,20 @@
XHRPolling.prototype._get = function(){
var self = this;
this._xhr = this._request(+ new Date, 'GET');
if ('onload' in this._xhr){
this._xhr.onload = function(){
self._onData(this.responseText);
self._get();
};
} else {
this._xhr.onreadystatechange = function(){
var status;
if (self._xhr.readyState == 4){
self._xhr.onreadystatechange = empty;
try { status = self._xhr.status; } catch(e){}
if (status == 200){
self._onData(self._xhr.responseText);
self._get();
} else {
self._onDisconnect();
}
}
};
}
this._xhr.send();
this._xhr.onreadystatechange = function(){
var status;
if (self._xhr.readyState == 4){
self._xhr.onreadystatechange = empty;
try { status = self._xhr.status; } catch(e){}
if (status == 200){
self._onData(self._xhr.responseText);
self._get();
} else {
self._onDisconnect();
}
}
};
this._xhr.send(null);
};
XHRPolling.check = function(){
@@ -65,4 +58,4 @@
return io.Transport.XHR.xdomainCheck();
};
})();
})();

View File

@@ -92,13 +92,17 @@
XHR.prototype._onDisconnect = function(){
if (this._xhr){
this._xhr.onreadystatechange = this._xhr.onload = empty;
this._xhr.abort();
this._xhr.onreadystatechange = empty;
try {
this._xhr.abort();
} catch(e){}
this._xhr = null;
}
if (this._sendXhr){
this._sendXhr.onreadystatechange = this._sendXhr.onload = empty;
this._sendXhr.abort();
this._sendXhr.onreadystatechange = empty;
try {
this._sendXhr.abort();
} catch(e){}
this._sendXhr = null;
}
this._sendBuffer = [];
@@ -128,4 +132,4 @@
XHR.request = request;
})();
})();

View File

@@ -15,7 +15,7 @@
ios: false,
load: function(fn){
if (document.readyState == 'complete' || _pageLoaded) return fn();
if (/loaded|complete/.test(document.readyState) || _pageLoaded) return fn();
if ('attachEvent' in window){
window.attachEvent('onload', fn);
} else {
@@ -57,4 +57,4 @@
_pageLoaded = true;
});
})();
})();

View File

@@ -1,4 +1,4 @@
/** Socket.IO 0.6 - Built with build.js */
/** Socket.IO 0.6.1 - Built with build.js */
/**
* Socket.IO client
*
@@ -8,12 +8,12 @@
*/
this.io = {
version: '0.6',
version: '0.6.1',
setPath: function(path){
if (window.console && console.error) console.error('io.setPath will be removed. Please set the variable WEB_SOCKET_SWF_LOCATION pointing to WebSocketMain.swf');
this.path = /\/$/.test(path) ? path : path + '/';
WEB_SOCKET_SWF_LOCATION = path + 'lib/vendor/web-socket-js/WebSocketMain.swf';
WEB_SOCKET_SWF_LOCATION = path + 'lib/vendor/web-socket-js/WebSocketMain.swf';
}
};
@@ -21,8 +21,10 @@ if ('jQuery' in this) jQuery.io = this.io;
if (typeof window != 'undefined'){
// WEB_SOCKET_SWF_LOCATION = (document.location.protocol == 'https:' ? 'https:' : 'http:') + '//cdn.socket.io/' + this.io.version + '/WebSocketMain.swf';
WEB_SOCKET_SWF_LOCATION = '/socket.io/lib/vendor/web-socket-js/WebSocketMain.swf';
if (typeof WEB_SOCKET_SWF_LOCATION === 'undefined')
WEB_SOCKET_SWF_LOCATION = '/socket.io/lib/vendor/web-socket-js/WebSocketMain.swf';
}
/**
* Socket.IO client
*
@@ -40,7 +42,7 @@ if (typeof window != 'undefined'){
ios: false,
load: function(fn){
if (document.readyState == 'complete' || _pageLoaded) return fn();
if (/loaded|complete/.test(document.readyState) || _pageLoaded) return fn();
if ('attachEvent' in window){
window.attachEvent('onload', fn);
} else {
@@ -83,6 +85,7 @@ if (typeof window != 'undefined'){
});
})();
/**
* Socket.IO client
*
@@ -318,13 +321,17 @@ if (typeof window != 'undefined'){
XHR.prototype._onDisconnect = function(){
if (this._xhr){
this._xhr.onreadystatechange = this._xhr.onload = empty;
this._xhr.abort();
this._xhr.onreadystatechange = empty;
try {
this._xhr.abort();
} catch(e){}
this._xhr = null;
}
if (this._sendXhr){
this._sendXhr.onreadystatechange = this._sendXhr.onload = empty;
this._sendXhr.abort();
this._sendXhr.onreadystatechange = empty;
try {
this._sendXhr.abort();
} catch(e){}
this._sendXhr = null;
}
this._sendBuffer = [];
@@ -355,6 +362,7 @@ if (typeof window != 'undefined'){
XHR.request = request;
})();
/**
* Socket.IO client
*
@@ -378,6 +386,7 @@ if (typeof window != 'undefined'){
this.socket = new WebSocket(this._prepareUrl());
this.socket.onmessage = function(ev){ self._onData(ev.data); };
this.socket.onclose = function(ev){ self._onClose(); };
this.socket.onerror = function(e){ self._onError(e); };
return this;
};
@@ -395,6 +404,10 @@ if (typeof window != 'undefined'){
this._onDisconnect();
return this;
};
WS.prototype._onError = function(e){
this.base.emit('error', [e]);
};
WS.prototype._prepareUrl = function(){
return (this.base.options.secure ? 'wss' : 'ws')
@@ -415,6 +428,7 @@ if (typeof window != 'undefined'){
};
})();
/**
* Socket.IO client
*
@@ -565,7 +579,7 @@ if (typeof window != 'undefined'){
this._xhr.onreadystatechange = function(){
if (self._xhr.readyState == 3) self._onData(self._xhr.responseText);
};
this._xhr.send();
this._xhr.send(null);
};
XHRMultipart.check = function(){
@@ -577,6 +591,7 @@ if (typeof window != 'undefined'){
};
})();
/**
* Socket.IO client
*
@@ -613,27 +628,20 @@ if (typeof window != 'undefined'){
XHRPolling.prototype._get = function(){
var self = this;
this._xhr = this._request(+ new Date, 'GET');
if ('onload' in this._xhr){
this._xhr.onload = function(){
self._onData(this.responseText);
self._get();
};
} else {
this._xhr.onreadystatechange = function(){
var status;
if (self._xhr.readyState == 4){
self._xhr.onreadystatechange = empty;
try { status = self._xhr.status; } catch(e){}
if (status == 200){
self._onData(self._xhr.responseText);
self._get();
} else {
self._onDisconnect();
}
}
};
}
this._xhr.send();
this._xhr.onreadystatechange = function(){
var status;
if (self._xhr.readyState == 4){
self._xhr.onreadystatechange = empty;
try { status = self._xhr.status; } catch(e){}
if (status == 200){
self._onData(self._xhr.responseText);
self._get();
} else {
self._onDisconnect();
}
}
};
this._xhr.send(null);
};
XHRPolling.check = function(){
@@ -645,6 +653,7 @@ if (typeof window != 'undefined'){
};
})();
/**
* Socket.IO client
*
@@ -825,7 +834,7 @@ JSONPPolling.xdomainCheck = function(){
this.transport.connect();
if (this.options.connectTimeout){
var self = this;
setTimeout(function(){
this.connectTimeoutTimer = setTimeout(function(){
if (!self.connected){
self.disconnect();
if (self.options.tryTransportsOnConnectTimeout && !self._rememberedTransport){
@@ -852,6 +861,7 @@ JSONPPolling.xdomainCheck = function(){
};
Socket.prototype.disconnect = function(){
if (this.connectTimeoutTimer) clearTimeout(this.connectTimeoutTimer);
this.transport.disconnect();
return this;
};
@@ -862,14 +872,15 @@ JSONPPolling.xdomainCheck = function(){
return this;
};
Socket.prototype.fire = function(name, args){
if (name in this._events){
for (var i = 0, ii = this._events[name].length; i < ii; i++)
this._events[name][i].apply(this, args === undefined ? [] : args);
}
return this;
};
Socket.prototype.emit = function(name, args){
if (name in this._events){
var events = this._events[name].concat();
for (var i = 0, ii = events.length; i < ii; i++)
events[i].apply(this, args === undefined ? [] : args);
}
return this;
};
Socket.prototype.removeEvent = function(name, fn){
if (name in this._events){
for (var a = 0, l = this._events[name].length; a < l; a++)
@@ -900,11 +911,11 @@ JSONPPolling.xdomainCheck = function(){
this.connecting = false;
this._doQueue();
if (this.options.rememberTransport) this.options.document.cookie = 'socketio=' + encodeURIComponent(this.transport.type);
this.fire('connect');
this.emit('connect');
};
Socket.prototype._onMessage = function(data){
this.fire('message', [data]);
this.emit('message', [data]);
};
Socket.prototype._onDisconnect = function(){
@@ -912,12 +923,15 @@ JSONPPolling.xdomainCheck = function(){
this.connected = false;
this.connecting = false;
this._queueStack = [];
if (wasConnected) this.fire('disconnect');
if (wasConnected) this.emit('disconnect');
};
Socket.prototype.fire = Socket.prototype.emit;
Socket.prototype.addListener = Socket.prototype.addEvent = Socket.prototype.addEventListener = Socket.prototype.on;
})();
/* SWFObject v2.2 <http://code.google.com/p/swfobject/>
is released under the MIT License <http://www.opensource.org/licenses/mit-license.php>
*/