arnaucube
arnaucube/raspberryGPIOhtmlserverPublic Self-hosted repository
raspberryGPIOhtmlserver/node_modules/engine.io-client/lib/transports/polling.js
node_modules/engine.io-client/lib/transports/polling.jsRaw
  1/**
  2 * Module dependencies.
  3 */
  4
  5var Transport = require('../transport');
  6var parseqs = require('parseqs');
  7var parser = require('engine.io-parser');
  8var inherit = require('component-inherit');
  9var debug = require('debug')('engine.io-client:polling');
 10
 11/**
 12 * Module exports.
 13 */
 14
 15module.exports = Polling;
 16
 17/**
 18 * Is XHR2 supported?
 19 */
 20
 21var hasXHR2 = (function() {
 22  var XMLHttpRequest = require('xmlhttprequest');
 23  var xhr = new XMLHttpRequest({ xdomain: false });
 24  return null != xhr.responseType;
 25})();
 26
 27/**
 28 * Polling interface.
 29 *
 30 * @param {Object} opts
 31 * @api private
 32 */
 33
 34function Polling(opts){
 35  var forceBase64 = (opts && opts.forceBase64);
 36  if (!hasXHR2 || forceBase64) {
 37    this.supportsBinary = false;
 38  }
 39  Transport.call(this, opts);
 40}
 41
 42/**
 43 * Inherits from Transport.
 44 */
 45
 46inherit(Polling, Transport);
 47
 48/**
 49 * Transport name.
 50 */
 51
 52Polling.prototype.name = 'polling';
 53
 54/**
 55 * Opens the socket (triggers polling). We write a PING message to determine
 56 * when the transport is open.
 57 *
 58 * @api private
 59 */
 60
 61Polling.prototype.doOpen = function(){
 62  this.poll();
 63};
 64
 65/**
 66 * Pauses polling.
 67 *
 68 * @param {Function} callback upon buffers are flushed and transport is paused
 69 * @api private
 70 */
 71
 72Polling.prototype.pause = function(onPause){
 73  var pending = 0;
 74  var self = this;
 75
 76  this.readyState = 'pausing';
 77
 78  function pause(){
 79    debug('paused');
 80    self.readyState = 'paused';
 81    onPause();
 82  }
 83
 84  if (this.polling || !this.writable) {
 85    var total = 0;
 86
 87    if (this.polling) {
 88      debug('we are currently polling - waiting to pause');
 89      total++;
 90      this.once('pollComplete', function(){
 91        debug('pre-pause polling complete');
 92        --total || pause();
 93      });
 94    }
 95
 96    if (!this.writable) {
 97      debug('we are currently writing - waiting to pause');
 98      total++;
 99      this.once('drain', function(){
100        debug('pre-pause writing complete');
101        --total || pause();
102      });
103    }
104  } else {
105    pause();
106  }
107};
108
109/**
110 * Starts polling cycle.
111 *
112 * @api public
113 */
114
115Polling.prototype.poll = function(){
116  debug('polling');
117  this.polling = true;
118  this.doPoll();
119  this.emit('poll');
120};
121
122/**
123 * Overloads onData to detect payloads.
124 *
125 * @api private
126 */
127
128Polling.prototype.onData = function(data){
129  var self = this;
130  debug('polling got data %s', data);
131  var callback = function(packet, index, total) {
132    // if its the first message we consider the transport open
133    if ('opening' == self.readyState) {
134      self.onOpen();
135    }
136
137    // if its a close packet, we close the ongoing requests
138    if ('close' == packet.type) {
139      self.onClose();
140      return false;
141    }
142
143    // otherwise bypass onData and handle the message
144    self.onPacket(packet);
145  };
146
147  // decode payload
148  parser.decodePayload(data, this.socket.binaryType, callback);
149
150  // if an event did not trigger closing
151  if ('closed' != this.readyState) {
152    // if we got data we're not polling
153    this.polling = false;
154    this.emit('pollComplete');
155
156    if ('open' == this.readyState) {
157      this.poll();
158    } else {
159      debug('ignoring poll - transport state "%s"', this.readyState);
160    }
161  }
162};
163
164/**
165 * For polling, send a close packet.
166 *
167 * @api private
168 */
169
170Polling.prototype.doClose = function(){
171  var self = this;
172
173  function close(){
174    debug('writing close packet');
175    self.write([{ type: 'close' }]);
176  }
177
178  if ('open' == this.readyState) {
179    debug('transport open - closing');
180    close();
181  } else {
182    // in case we're trying to close while
183    // handshaking is in progress (GH-164)
184    debug('transport not open - deferring close');
185    this.once('open', close);
186  }
187};
188
189/**
190 * Writes a packets payload.
191 *
192 * @param {Array} data packets
193 * @param {Function} drain callback
194 * @api private
195 */
196
197Polling.prototype.write = function(packets){
198  var self = this;
199  this.writable = false;
200  var callbackfn = function() {
201    self.writable = true;
202    self.emit('drain');
203  };
204
205  var self = this;
206  parser.encodePayload(packets, this.supportsBinary, function(data) {
207    self.doWrite(data, callbackfn);
208  });
209};
210
211/**
212 * Generates uri for connection.
213 *
214 * @api private
215 */
216
217Polling.prototype.uri = function(){
218  var query = this.query || {};
219  var schema = this.secure ? 'https' : 'http';
220  var port = '';
221
222  // cache busting is forced
223  if (false !== this.timestampRequests) {
224    query[this.timestampParam] = +new Date + '-' + Transport.timestamps++;
225  }
226
227  if (!this.supportsBinary && !query.sid) {
228    query.b64 = 1;
229  }
230
231  query = parseqs.encode(query);
232
233  // avoid port if default for schema
234  if (this.port && (('https' == schema && this.port != 443) ||
235     ('http' == schema && this.port != 80))) {
236    port = ':' + this.port;
237  }
238
239  // prepend ? to query
240  if (query.length) {
241    query = '?' + query;
242  }
243
244  return schema + '://' + this.hostname + port + this.path + query;
245};