Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
s3
s3
*.swp
70 changes: 69 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,74 @@ Events:
* Added io.util.ios which reports if the UA is running on iPhone or iPad
* No more loading bar on iPhone: XHR-Polling now connects `onload` for the iOS WebKit, and waits 10 ms to launch the initial connection.

2010 11 01 - **0.6.0**

* Make sure to only destroy if the _iframe was created
* Removed flashsocket onClose logic since its handled by connectTimeout
* Added socket checks when disconnecting / sending messages
* Fixed semicolons (thanks SINPacifist)
* Added io.util.merge for options merging. Thanks SINPacifist
* Removed unnecessary onClose handling, since this is taken care by Socket (thanks SINPacifist)
* Make sure not to try other transports if the socket.io cookie was there
* Updated web-socket-js
* Make sure not to abort the for loop when skipping the transport
* Connect timeout (fixes #34)
* Try different transports upon connect timeout (fixes #35)
* Restored rememberTransport to default
* Removed io.setPath check
* Make sure IE7 doesn't err on the multipart feature detection. Thanks Davin Lunz
* CORS feature detection. Fixes IE7 attempting cross domain requests through their incomplete XMLHttpRequest implementation.
* Now altering WEB_SOCKET_SWF_LOCATION (this way we don't need the web-socket-js WebSocket object to be there)
* Flashsocket .connect() and .send() call addTask.
* Make sure flashsocket can only be loaded on browsers that don't have a native websocket
* Leveraging __addTask to delay sent messages until WebSocket through SWF is fully loaded.
* Removed __isFlashLite check
* Leverage node.js serving of the client side files
* Make sure we can load io.js from node (window check)
* Fix for XDomain send() on IE8 (thanks Eric Zhang)
* Added a note about cross domain .swf files
* Made sure no errors where thrown in IE if there isn't a flash fallback available.
* Make sure disconnect event is only fired if the socket was completely connected, and it's not a reconnection attempt that was interrupted.
* Force disconnection if .connect() is called and a connection attempt is ongoing
* Upon socket disconnection, also mark `connecting` as false
* .connecting flag in transport instance
* Make sure .connecting is cleared in transport
* Correct sessionid checking
* Clear sessionid upon disconnection
* Remove _xhr and _sendXhr objects
* Moved timeout default into Transport
* Remove callbacks on _onDisconnect and call abort()
* Added placeholder for direct disconnect in XHR
* Timeout logic (fixes #31)
* Don't check for data length to trigger _onData, since most transports are not doing it
* Set timeout defaults based on heartbeat interval and polling duration (since we dont do heartbeats for polling)
* Check for msgs.length _onData
* Removed unused client option (heartbeatInterval)
* Added onDisconnect call if long poll is interrupted
* Polling calls _get directly as opposed to connect()
* Disconnection handling upon failure to send a message through xhr-* transports.
* Clean up internal xhr buffer upon disconnection
* Clean up general buffer in Socket upon disconnection
* Mark socket as disconnected
* Opera 10 support
* Fix for .fire on IE being called without arguments (fixes #28)
* JSONP polling transport
* Android compatibility.
* Automatic JSON decoding support
* Automatic JSON encoding support for objects
* Adding test for android for delaying the connection (fixes spinner)
* Fixing a few dangerous loops that otherwise loop into properties that have been added to the prototype elsewhere.
* Support for initializing io.Socket after the page has been loaded

2010 11 ?? - **0.7.0**

* Fixed, improved and added missing Transport#disconnect methods
* Implemented data.js (data and message encoding and decoding with buffering)
- Fixes edge cases with multipart not sending the entirety of a message and
firing the data event
* Implemented forced disconnect call from server
* Added warning if JSON.parse is not available and a JSON message is received

### Credits

Guillermo Rauch <guillermo@learnboost.com>
Expand Down Expand Up @@ -210,4 +278,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.
3 changes: 2 additions & 1 deletion bin/build
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ var fs = require('fs'),
files = [
'io.js',
'util.js',
'data.js',
'transport.js',
'transports/xhr.js',
'transports/websocket.js',
Expand Down Expand Up @@ -47,4 +48,4 @@ sys.log('Generating…');
fs.write(fs.openSync(__dirname + '/../socket.io.js', 'w'), content, 0, 'utf8');
sys.log(' + ' + __dirname + '/../socket.io.js');

sys.log('All done!');
sys.log('All done!');
232 changes: 232 additions & 0 deletions lib/data.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,232 @@
/**
* Socket.IO client
*
* @author Guillermo Rauch <guillermo@learnboost.com>
* @license The MIT license.
* @copyright Copyright (c) 2010 LearnBoost <dev@learnboost.com>
*/

io.data = {};

/**
* Data decoder class
*
* @api public
*/

io.data.Decoder = function(){
this.reset();
this.buffer = '';
this.events = {};
};

io.data.Decoder.prototype = {

/**
* Add data to the buffer for parsing
*
* @param {String} data
* @api public
*/
add: function(data){
this.buffer += data;
this.parse();
},

/**
* Parse the current buffer
*
* @api private
*/
parse: function(){
for (var l = this.buffer.length; this.i < l; this.i++){
var chr = this.buffer[this.i];
if (this.type === undefined){
if (chr == ':') return this.error('Data type not specified');
this.type = '' + chr;
continue;
}
if (this.length === undefined && chr == ':'){
this.length = '';
continue;
}
if (this.data === undefined){
if (chr != ':'){
this.length += chr;
} else {
if (this.length.length === 0)
return this.error('Data length not specified');
this.length = Number(this.length);
this.data = '';
}
continue;
}
if (this.data.length === this.length){
if (chr == ','){
this.emit('data', this.type, this.data);
this.buffer = this.buffer.substr(this.i + 1);
this.reset();
return this.parse();
} else {
return this.error('Termination character "," expected');
}
} else {
this.data += chr;
}
}
},

/**
* Reset the parser state
*
* @api private
*/

reset: function(){
this.i = 0;
this.type = this.data = this.length = undefined;
},

/**
* Error handling functions
*
* @param {String} reason to report
* @api private
*/

error: function(reason){
this.reset();
this.emit('error', reason);
},

/**
* Emits an event
*
* @param {String} ev name
* @api public
*/

emit: function(ev){
if (!(ev in this.events))
return this;
for (var i = 0, l = this.events[ev].length; i < l; i++)
if (this.events[ev][i])
this.events[ev][i].apply(this, Array.prototype.slice.call(arguments).slice(1));
return this;
},

/**
* Adds an event listener
*
* @param {String} ev name
* @param {Function} callback
* @api public
*/

on: function(ev, fn){
if (!(ev in this.events))
this.events[ev] = [];
this.events[ev].push(fn);
return this;
},

/**
* Removes an event listener
*
* @param {String} ev name
* @param {Function} callback
* @api public
*/

removeListener: function(ev, fn){
if (!(ev in this.events))
return this;
for (var i = 0, l = this.events[ev].length; i < l; i++)
if (this.events[ev][i] == fn)
this.events[ev].splice(i, 1);
return this;
}

};

/**
* Encode function
*
* Examples:
* encode([3, 'Message of type 3']);
* encode([[1, 'Message of type 1], [2, 'Message of type 2]]);
*
* @param {Array} list of messages
* @api public
*/

io.data.encode = function(messages){
messages = io.util.isArray(messages[0]) ? messages : [messages];
var ret = '';
for (var i = 0, str; i < messages.length; i++){
str = String(messages[i][1]);
if (str === undefined || str === null) str = '';
ret += messages[i][0] + ':' + str.length + ':' + str + ',';
}
return ret;
};

/**
* Encode message function
*
* @param {String} message
* @param {Object} annotations
* @api public
*/

io.data.encodeMessage = function(msg, annotations){
var data = ''
, anns = annotations || {};
for (var k in anns){
v = anns[k];
data += k + (v !== null && v !== undefined ? ':' + v : '') + "\n";
}
data += ':' + (msg === undefined || msg === null ? '' : msg);
return data;
};

/**
* Decode message function
*
* @param {String} message
* @api public
*/

io.data.decodeMessage = function(msg){
var anns = {}
, data;
for (var i = 0, chr, key, value, l = msg.length; i < l; i++){
chr = msg[i];
if (i === 0 && chr === ':'){
data = msg.substr(1);
break;
}
if (key == null && value == null && chr == ':'){
data = msg.substr(i + 1);
break;
}
if (chr === "\n"){
anns[key] = value;
key = value = undefined;
continue;
}
if (key === undefined){
key = chr;
continue;
}
if (value === undefined && chr == ':'){
value = '';
continue;
}
if (value !== undefined)
value += chr;
else
key += chr;
}
return [data, anns];
};
7 changes: 4 additions & 3 deletions lib/io.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
*/

this.io = {
version: '0.6',
version: '0.7pre',

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');
Expand All @@ -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';
}
Loading