/js/lib/Socket.IO-node/support/socket.io-client/lib/transport.js
JavaScript | 142 lines | 115 code | 19 blank | 8 comment | 25 complexity | e0995767d65c44d423bf2e1cc9d2b3ab MD5 | raw file
Possible License(s): GPL-2.0, LGPL-2.1, MPL-2.0-no-copyleft-exception, BSD-3-Clause
- /**
- * Socket.IO client
- *
- * @author Guillermo Rauch <guillermo@learnboost.com>
- * @license The MIT license.
- * @copyright Copyright (c) 2010 LearnBoost <dev@learnboost.com>
- */
- // abstract
- (function(){
- var io = this.io;
-
- var frame = '~m~',
-
- stringify = function(message){
- if (Object.prototype.toString.call(message) == '[object Object]'){
- if (!('JSON' in window)){
- if ('console' in window && console.error) console.error('Trying to encode as JSON, but JSON.stringify is missing.');
- return '{ "$error": "Invalid message" }';
- }
- return '~j~' + JSON.stringify(message);
- } else {
- return String(message);
- }
- };
-
- Transport = io.Transport = function(base, options){
- this.base = base;
- this.options = {
- timeout: 15000 // based on heartbeat interval default
- };
- io.util.merge(this.options, options);
- };
- Transport.prototype.send = function(){
- throw new Error('Missing send() implementation');
- };
- Transport.prototype.connect = function(){
- throw new Error('Missing connect() implementation');
- };
- Transport.prototype.disconnect = function(){
- throw new Error('Missing disconnect() implementation');
- };
-
- Transport.prototype._encode = function(messages){
- var ret = '', message,
- messages = io.util.isArray(messages) ? messages : [messages];
- for (var i = 0, l = messages.length; i < l; i++){
- message = messages[i] === null || messages[i] === undefined ? '' : stringify(messages[i]);
- ret += frame + message.length + frame + message;
- }
- return ret;
- };
-
- Transport.prototype._decode = function(data){
- var messages = [], number, n;
- do {
- if (data.substr(0, 3) !== frame) return messages;
- data = data.substr(3);
- number = '', n = '';
- for (var i = 0, l = data.length; i < l; i++){
- n = Number(data.substr(i, 1));
- if (data.substr(i, 1) == n){
- number += n;
- } else {
- data = data.substr(number.length + frame.length);
- number = Number(number);
- break;
- }
- }
- messages.push(data.substr(0, number)); // here
- data = data.substr(number);
- } while(data !== '');
- return messages;
- };
-
- Transport.prototype._onData = function(data){
- this._setTimeout();
- var msgs = this._decode(data);
- if (msgs && msgs.length){
- for (var i = 0, l = msgs.length; i < l; i++){
- this._onMessage(msgs[i]);
- }
- }
- };
-
- Transport.prototype._setTimeout = function(){
- var self = this;
- if (this._timeout) clearTimeout(this._timeout);
- this._timeout = setTimeout(function(){
- self._onTimeout();
- }, this.options.timeout);
- };
-
- Transport.prototype._onTimeout = function(){
- this._onDisconnect();
- };
-
- Transport.prototype._onMessage = function(message){
- if (!this.sessionid){
- this.sessionid = message;
- this._onConnect();
- } else if (message.substr(0, 3) == '~h~'){
- this._onHeartbeat(message.substr(3));
- } else if (message.substr(0, 3) == '~j~'){
- this.base._onMessage(JSON.parse(message.substr(3)));
- } else {
- this.base._onMessage(message);
- }
- },
-
- Transport.prototype._onHeartbeat = function(heartbeat){
- this.send('~h~' + heartbeat); // echo
- };
-
- Transport.prototype._onConnect = function(){
- this.connected = true;
- this.connecting = false;
- this.base._onConnect();
- this._setTimeout();
- };
- Transport.prototype._onDisconnect = function(){
- this.connecting = false;
- this.connected = false;
- this.sessionid = null;
- this.base._onDisconnect();
- };
- Transport.prototype._prepareUrl = function(){
- return (this.base.options.secure ? 'https' : 'http')
- + '://' + this.base.host
- + ':' + this.base.options.port
- + '/' + this.base.options.resource
- + '/' + this.type
- + (this.sessionid ? ('/' + this.sessionid) : '/');
- };
- })();