PageRenderTime 81ms CodeModel.GetById 40ms app.highlight 12ms RepoModel.GetById 22ms app.codeStats 0ms

/js/lib/Socket.IO-node/support/socket.io-client/lib/transport.js

http://github.com/onedayitwillmake/RealtimeMultiplayerNodeJs
JavaScript | 142 lines | 115 code | 19 blank | 8 comment | 25 complexity | e0995767d65c44d423bf2e1cc9d2b3ab MD5 | raw file
  1/**
  2 * Socket.IO client
  3 * 
  4 * @author Guillermo Rauch <guillermo@learnboost.com>
  5 * @license The MIT license.
  6 * @copyright Copyright (c) 2010 LearnBoost <dev@learnboost.com>
  7 */
  8
  9// abstract
 10
 11(function(){
 12	var io = this.io;
 13	
 14	var frame = '~m~',
 15	
 16	stringify = function(message){
 17		if (Object.prototype.toString.call(message) == '[object Object]'){
 18			if (!('JSON' in window)){
 19				if ('console' in window && console.error) console.error('Trying to encode as JSON, but JSON.stringify is missing.');
 20				return '{ "$error": "Invalid message" }';
 21			}
 22			return '~j~' + JSON.stringify(message);
 23		} else {
 24			return String(message);
 25		}
 26	};
 27	
 28	Transport = io.Transport = function(base, options){
 29		this.base = base;
 30		this.options = {
 31			timeout: 15000 // based on heartbeat interval default
 32		};
 33		io.util.merge(this.options, options);
 34	};
 35
 36	Transport.prototype.send = function(){
 37		throw new Error('Missing send() implementation');
 38	};
 39
 40	Transport.prototype.connect = function(){
 41		throw new Error('Missing connect() implementation');
 42	};
 43
 44	Transport.prototype.disconnect = function(){
 45		throw new Error('Missing disconnect() implementation');
 46	};
 47	
 48	Transport.prototype._encode = function(messages){
 49		var ret = '', message,
 50				messages = io.util.isArray(messages) ? messages : [messages];
 51		for (var i = 0, l = messages.length; i < l; i++){
 52			message = messages[i] === null || messages[i] === undefined ? '' : stringify(messages[i]);
 53			ret += frame + message.length + frame + message;
 54		}
 55		return ret;
 56	};
 57	
 58	Transport.prototype._decode = function(data){
 59		var messages = [], number, n;
 60		do {
 61			if (data.substr(0, 3) !== frame) return messages;
 62			data = data.substr(3);
 63			number = '', n = '';
 64			for (var i = 0, l = data.length; i < l; i++){
 65				n = Number(data.substr(i, 1));
 66				if (data.substr(i, 1) == n){
 67					number += n;
 68				} else {	
 69					data = data.substr(number.length + frame.length);
 70					number = Number(number);
 71					break;
 72				} 
 73			}
 74			messages.push(data.substr(0, number)); // here
 75			data = data.substr(number);
 76		} while(data !== '');
 77		return messages;
 78	};
 79	
 80	Transport.prototype._onData = function(data){
 81		this._setTimeout();
 82		var msgs = this._decode(data);
 83		if (msgs && msgs.length){
 84			for (var i = 0, l = msgs.length; i < l; i++){
 85				this._onMessage(msgs[i]);
 86			}
 87		}
 88	};
 89	
 90	Transport.prototype._setTimeout = function(){
 91		var self = this;
 92		if (this._timeout) clearTimeout(this._timeout);
 93		this._timeout = setTimeout(function(){
 94			self._onTimeout();
 95		}, this.options.timeout);
 96	};
 97	
 98	Transport.prototype._onTimeout = function(){
 99		this._onDisconnect();
100	};
101	
102	Transport.prototype._onMessage = function(message){
103		if (!this.sessionid){
104			this.sessionid = message;
105			this._onConnect();
106		} else if (message.substr(0, 3) == '~h~'){
107			this._onHeartbeat(message.substr(3));
108		} else if (message.substr(0, 3) == '~j~'){
109			this.base._onMessage(JSON.parse(message.substr(3)));
110		} else {
111			this.base._onMessage(message);
112		}
113	},
114	
115	Transport.prototype._onHeartbeat = function(heartbeat){
116		this.send('~h~' + heartbeat); // echo
117	};
118	
119	Transport.prototype._onConnect = function(){
120		this.connected = true;
121		this.connecting = false;
122		this.base._onConnect();
123		this._setTimeout();
124	};
125
126	Transport.prototype._onDisconnect = function(){
127		this.connecting = false;
128		this.connected = false;
129		this.sessionid = null;
130		this.base._onDisconnect();
131	};
132
133	Transport.prototype._prepareUrl = function(){
134		return (this.base.options.secure ? 'https' : 'http') 
135			+ '://' + this.base.host 
136			+ ':' + this.base.options.port
137			+ '/' + this.base.options.resource
138			+ '/' + this.type
139			+ (this.sessionid ? ('/' + this.sessionid) : '/');
140	};
141
142})();