PageRenderTime 63ms CodeModel.GetById 21ms RepoModel.GetById 0ms app.codeStats 2ms

/node_modules/socket.io/node_modules/socket.io-client/socket.io.js

https://github.com/kirillKey/questSearchTrain
JavaScript | 6252 lines | 3546 code | 966 blank | 1740 comment | 1013 complexity | 44d1b2a6025c12a3af3c0d9586ca0608 MD5 | raw file
Possible License(s): Apache-2.0, MIT, 0BSD, GPL-2.0, BSD-3-Clause

Large files files are truncated, but you can click here to view the full file

  1. !function(e){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=e();else if("function"==typeof define&&define.amd)define([],e);else{var f;"undefined"!=typeof window?f=window:"undefined"!=typeof global?f=global:"undefined"!=typeof self&&(f=self),f.io=e()}}(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);throw new Error("Cannot find module '"+o+"'")}var f=n[o]={exports:{}};t[o][0].call(f.exports,function(e){var n=t[o][1][e];return s(n?n:e)},f,f.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(_dereq_,module,exports){
  2. module.exports = _dereq_('./lib/');
  3. },{"./lib/":2}],2:[function(_dereq_,module,exports){
  4. /**
  5. * Module dependencies.
  6. */
  7. var url = _dereq_('./url');
  8. var parser = _dereq_('socket.io-parser');
  9. var Manager = _dereq_('./manager');
  10. var debug = _dereq_('debug')('socket.io-client');
  11. /**
  12. * Module exports.
  13. */
  14. module.exports = exports = lookup;
  15. /**
  16. * Managers cache.
  17. */
  18. var cache = exports.managers = {};
  19. /**
  20. * Looks up an existing `Manager` for multiplexing.
  21. * If the user summons:
  22. *
  23. * `io('http://localhost/a');`
  24. * `io('http://localhost/b');`
  25. *
  26. * We reuse the existing instance based on same scheme/port/host,
  27. * and we initialize sockets for each namespace.
  28. *
  29. * @api public
  30. */
  31. function lookup(uri, opts) {
  32. if (typeof uri == 'object') {
  33. opts = uri;
  34. uri = undefined;
  35. }
  36. opts = opts || {};
  37. var parsed = url(uri);
  38. var source = parsed.source;
  39. var id = parsed.id;
  40. var io;
  41. if (opts.forceNew || opts['force new connection'] || false === opts.multiplex) {
  42. debug('ignoring socket cache for %s', source);
  43. io = Manager(source, opts);
  44. } else {
  45. if (!cache[id]) {
  46. debug('new io instance for %s', source);
  47. cache[id] = Manager(source, opts);
  48. }
  49. io = cache[id];
  50. }
  51. return io.socket(parsed.path);
  52. }
  53. /**
  54. * Protocol version.
  55. *
  56. * @api public
  57. */
  58. exports.protocol = parser.protocol;
  59. /**
  60. * `connect`.
  61. *
  62. * @param {String} uri
  63. * @api public
  64. */
  65. exports.connect = lookup;
  66. /**
  67. * Expose constructors for standalone build.
  68. *
  69. * @api public
  70. */
  71. exports.Manager = _dereq_('./manager');
  72. exports.Socket = _dereq_('./socket');
  73. },{"./manager":3,"./socket":5,"./url":6,"debug":9,"socket.io-parser":40}],3:[function(_dereq_,module,exports){
  74. /**
  75. * Module dependencies.
  76. */
  77. var url = _dereq_('./url');
  78. var eio = _dereq_('engine.io-client');
  79. var Socket = _dereq_('./socket');
  80. var Emitter = _dereq_('component-emitter');
  81. var parser = _dereq_('socket.io-parser');
  82. var on = _dereq_('./on');
  83. var bind = _dereq_('component-bind');
  84. var object = _dereq_('object-component');
  85. var debug = _dereq_('debug')('socket.io-client:manager');
  86. var indexOf = _dereq_('indexof');
  87. /**
  88. * Module exports
  89. */
  90. module.exports = Manager;
  91. /**
  92. * `Manager` constructor.
  93. *
  94. * @param {String} engine instance or engine uri/opts
  95. * @param {Object} options
  96. * @api public
  97. */
  98. function Manager(uri, opts){
  99. if (!(this instanceof Manager)) return new Manager(uri, opts);
  100. if (uri && ('object' == typeof uri)) {
  101. opts = uri;
  102. uri = undefined;
  103. }
  104. opts = opts || {};
  105. opts.path = opts.path || '/socket.io';
  106. this.nsps = {};
  107. this.subs = [];
  108. this.opts = opts;
  109. this.reconnection(opts.reconnection !== false);
  110. this.reconnectionAttempts(opts.reconnectionAttempts || Infinity);
  111. this.reconnectionDelay(opts.reconnectionDelay || 1000);
  112. this.reconnectionDelayMax(opts.reconnectionDelayMax || 5000);
  113. this.timeout(null == opts.timeout ? 20000 : opts.timeout);
  114. this.readyState = 'closed';
  115. this.uri = uri;
  116. this.connected = [];
  117. this.attempts = 0;
  118. this.encoding = false;
  119. this.packetBuffer = [];
  120. this.encoder = new parser.Encoder();
  121. this.decoder = new parser.Decoder();
  122. this.autoConnect = opts.autoConnect !== false;
  123. if (this.autoConnect) this.open();
  124. }
  125. /**
  126. * Propagate given event to sockets and emit on `this`
  127. *
  128. * @api private
  129. */
  130. Manager.prototype.emitAll = function() {
  131. this.emit.apply(this, arguments);
  132. for (var nsp in this.nsps) {
  133. this.nsps[nsp].emit.apply(this.nsps[nsp], arguments);
  134. }
  135. };
  136. /**
  137. * Mix in `Emitter`.
  138. */
  139. Emitter(Manager.prototype);
  140. /**
  141. * Sets the `reconnection` config.
  142. *
  143. * @param {Boolean} true/false if it should automatically reconnect
  144. * @return {Manager} self or value
  145. * @api public
  146. */
  147. Manager.prototype.reconnection = function(v){
  148. if (!arguments.length) return this._reconnection;
  149. this._reconnection = !!v;
  150. return this;
  151. };
  152. /**
  153. * Sets the reconnection attempts config.
  154. *
  155. * @param {Number} max reconnection attempts before giving up
  156. * @return {Manager} self or value
  157. * @api public
  158. */
  159. Manager.prototype.reconnectionAttempts = function(v){
  160. if (!arguments.length) return this._reconnectionAttempts;
  161. this._reconnectionAttempts = v;
  162. return this;
  163. };
  164. /**
  165. * Sets the delay between reconnections.
  166. *
  167. * @param {Number} delay
  168. * @return {Manager} self or value
  169. * @api public
  170. */
  171. Manager.prototype.reconnectionDelay = function(v){
  172. if (!arguments.length) return this._reconnectionDelay;
  173. this._reconnectionDelay = v;
  174. return this;
  175. };
  176. /**
  177. * Sets the maximum delay between reconnections.
  178. *
  179. * @param {Number} delay
  180. * @return {Manager} self or value
  181. * @api public
  182. */
  183. Manager.prototype.reconnectionDelayMax = function(v){
  184. if (!arguments.length) return this._reconnectionDelayMax;
  185. this._reconnectionDelayMax = v;
  186. return this;
  187. };
  188. /**
  189. * Sets the connection timeout. `false` to disable
  190. *
  191. * @return {Manager} self or value
  192. * @api public
  193. */
  194. Manager.prototype.timeout = function(v){
  195. if (!arguments.length) return this._timeout;
  196. this._timeout = v;
  197. return this;
  198. };
  199. /**
  200. * Starts trying to reconnect if reconnection is enabled and we have not
  201. * started reconnecting yet
  202. *
  203. * @api private
  204. */
  205. Manager.prototype.maybeReconnectOnOpen = function() {
  206. // Only try to reconnect if it's the first time we're connecting
  207. if (!this.openReconnect && !this.reconnecting && this._reconnection && this.attempts === 0) {
  208. // keeps reconnection from firing twice for the same reconnection loop
  209. this.openReconnect = true;
  210. this.reconnect();
  211. }
  212. };
  213. /**
  214. * Sets the current transport `socket`.
  215. *
  216. * @param {Function} optional, callback
  217. * @return {Manager} self
  218. * @api public
  219. */
  220. Manager.prototype.open =
  221. Manager.prototype.connect = function(fn){
  222. debug('readyState %s', this.readyState);
  223. if (~this.readyState.indexOf('open')) return this;
  224. debug('opening %s', this.uri);
  225. this.engine = eio(this.uri, this.opts);
  226. var socket = this.engine;
  227. var self = this;
  228. this.readyState = 'opening';
  229. this.skipReconnect = false;
  230. // emit `open`
  231. var openSub = on(socket, 'open', function() {
  232. self.onopen();
  233. fn && fn();
  234. });
  235. // emit `connect_error`
  236. var errorSub = on(socket, 'error', function(data){
  237. debug('connect_error');
  238. self.cleanup();
  239. self.readyState = 'closed';
  240. self.emitAll('connect_error', data);
  241. if (fn) {
  242. var err = new Error('Connection error');
  243. err.data = data;
  244. fn(err);
  245. }
  246. self.maybeReconnectOnOpen();
  247. });
  248. // emit `connect_timeout`
  249. if (false !== this._timeout) {
  250. var timeout = this._timeout;
  251. debug('connect attempt will timeout after %d', timeout);
  252. // set timer
  253. var timer = setTimeout(function(){
  254. debug('connect attempt timed out after %d', timeout);
  255. openSub.destroy();
  256. socket.close();
  257. socket.emit('error', 'timeout');
  258. self.emitAll('connect_timeout', timeout);
  259. }, timeout);
  260. this.subs.push({
  261. destroy: function(){
  262. clearTimeout(timer);
  263. }
  264. });
  265. }
  266. this.subs.push(openSub);
  267. this.subs.push(errorSub);
  268. return this;
  269. };
  270. /**
  271. * Called upon transport open.
  272. *
  273. * @api private
  274. */
  275. Manager.prototype.onopen = function(){
  276. debug('open');
  277. // clear old subs
  278. this.cleanup();
  279. // mark as open
  280. this.readyState = 'open';
  281. this.emit('open');
  282. // add new subs
  283. var socket = this.engine;
  284. this.subs.push(on(socket, 'data', bind(this, 'ondata')));
  285. this.subs.push(on(this.decoder, 'decoded', bind(this, 'ondecoded')));
  286. this.subs.push(on(socket, 'error', bind(this, 'onerror')));
  287. this.subs.push(on(socket, 'close', bind(this, 'onclose')));
  288. };
  289. /**
  290. * Called with data.
  291. *
  292. * @api private
  293. */
  294. Manager.prototype.ondata = function(data){
  295. this.decoder.add(data);
  296. };
  297. /**
  298. * Called when parser fully decodes a packet.
  299. *
  300. * @api private
  301. */
  302. Manager.prototype.ondecoded = function(packet) {
  303. this.emit('packet', packet);
  304. };
  305. /**
  306. * Called upon socket error.
  307. *
  308. * @api private
  309. */
  310. Manager.prototype.onerror = function(err){
  311. debug('error', err);
  312. this.emitAll('error', err);
  313. };
  314. /**
  315. * Creates a new socket for the given `nsp`.
  316. *
  317. * @return {Socket}
  318. * @api public
  319. */
  320. Manager.prototype.socket = function(nsp){
  321. var socket = this.nsps[nsp];
  322. if (!socket) {
  323. socket = new Socket(this, nsp);
  324. this.nsps[nsp] = socket;
  325. var self = this;
  326. socket.on('connect', function(){
  327. if (!~indexOf(self.connected, socket)) {
  328. self.connected.push(socket);
  329. }
  330. });
  331. }
  332. return socket;
  333. };
  334. /**
  335. * Called upon a socket close.
  336. *
  337. * @param {Socket} socket
  338. */
  339. Manager.prototype.destroy = function(socket){
  340. var index = indexOf(this.connected, socket);
  341. if (~index) this.connected.splice(index, 1);
  342. if (this.connected.length) return;
  343. this.close();
  344. };
  345. /**
  346. * Writes a packet.
  347. *
  348. * @param {Object} packet
  349. * @api private
  350. */
  351. Manager.prototype.packet = function(packet){
  352. debug('writing packet %j', packet);
  353. var self = this;
  354. if (!self.encoding) {
  355. // encode, then write to engine with result
  356. self.encoding = true;
  357. this.encoder.encode(packet, function(encodedPackets) {
  358. for (var i = 0; i < encodedPackets.length; i++) {
  359. self.engine.write(encodedPackets[i]);
  360. }
  361. self.encoding = false;
  362. self.processPacketQueue();
  363. });
  364. } else { // add packet to the queue
  365. self.packetBuffer.push(packet);
  366. }
  367. };
  368. /**
  369. * If packet buffer is non-empty, begins encoding the
  370. * next packet in line.
  371. *
  372. * @api private
  373. */
  374. Manager.prototype.processPacketQueue = function() {
  375. if (this.packetBuffer.length > 0 && !this.encoding) {
  376. var pack = this.packetBuffer.shift();
  377. this.packet(pack);
  378. }
  379. };
  380. /**
  381. * Clean up transport subscriptions and packet buffer.
  382. *
  383. * @api private
  384. */
  385. Manager.prototype.cleanup = function(){
  386. var sub;
  387. while (sub = this.subs.shift()) sub.destroy();
  388. this.packetBuffer = [];
  389. this.encoding = false;
  390. this.decoder.destroy();
  391. };
  392. /**
  393. * Close the current socket.
  394. *
  395. * @api private
  396. */
  397. Manager.prototype.close =
  398. Manager.prototype.disconnect = function(){
  399. this.skipReconnect = true;
  400. this.readyState = 'closed';
  401. this.engine && this.engine.close();
  402. };
  403. /**
  404. * Called upon engine close.
  405. *
  406. * @api private
  407. */
  408. Manager.prototype.onclose = function(reason){
  409. debug('close');
  410. this.cleanup();
  411. this.readyState = 'closed';
  412. this.emit('close', reason);
  413. if (this._reconnection && !this.skipReconnect) {
  414. this.reconnect();
  415. }
  416. };
  417. /**
  418. * Attempt a reconnection.
  419. *
  420. * @api private
  421. */
  422. Manager.prototype.reconnect = function(){
  423. if (this.reconnecting || this.skipReconnect) return this;
  424. var self = this;
  425. this.attempts++;
  426. if (this.attempts > this._reconnectionAttempts) {
  427. debug('reconnect failed');
  428. this.emitAll('reconnect_failed');
  429. this.reconnecting = false;
  430. } else {
  431. var delay = this.attempts * this.reconnectionDelay();
  432. delay = Math.min(delay, this.reconnectionDelayMax());
  433. debug('will wait %dms before reconnect attempt', delay);
  434. this.reconnecting = true;
  435. var timer = setTimeout(function(){
  436. if (self.skipReconnect) return;
  437. debug('attempting reconnect');
  438. self.emitAll('reconnect_attempt', self.attempts);
  439. self.emitAll('reconnecting', self.attempts);
  440. // check again for the case socket closed in above events
  441. if (self.skipReconnect) return;
  442. self.open(function(err){
  443. if (err) {
  444. debug('reconnect attempt error');
  445. self.reconnecting = false;
  446. self.reconnect();
  447. self.emitAll('reconnect_error', err.data);
  448. } else {
  449. debug('reconnect success');
  450. self.onreconnect();
  451. }
  452. });
  453. }, delay);
  454. this.subs.push({
  455. destroy: function(){
  456. clearTimeout(timer);
  457. }
  458. });
  459. }
  460. };
  461. /**
  462. * Called upon successful reconnect.
  463. *
  464. * @api private
  465. */
  466. Manager.prototype.onreconnect = function(){
  467. var attempt = this.attempts;
  468. this.attempts = 0;
  469. this.reconnecting = false;
  470. this.emitAll('reconnect', attempt);
  471. };
  472. },{"./on":4,"./socket":5,"./url":6,"component-bind":7,"component-emitter":8,"debug":9,"engine.io-client":10,"indexof":36,"object-component":37,"socket.io-parser":40}],4:[function(_dereq_,module,exports){
  473. /**
  474. * Module exports.
  475. */
  476. module.exports = on;
  477. /**
  478. * Helper for subscriptions.
  479. *
  480. * @param {Object|EventEmitter} obj with `Emitter` mixin or `EventEmitter`
  481. * @param {String} event name
  482. * @param {Function} callback
  483. * @api public
  484. */
  485. function on(obj, ev, fn) {
  486. obj.on(ev, fn);
  487. return {
  488. destroy: function(){
  489. obj.removeListener(ev, fn);
  490. }
  491. };
  492. }
  493. },{}],5:[function(_dereq_,module,exports){
  494. /**
  495. * Module dependencies.
  496. */
  497. var parser = _dereq_('socket.io-parser');
  498. var Emitter = _dereq_('component-emitter');
  499. var toArray = _dereq_('to-array');
  500. var on = _dereq_('./on');
  501. var bind = _dereq_('component-bind');
  502. var debug = _dereq_('debug')('socket.io-client:socket');
  503. var hasBin = _dereq_('has-binary');
  504. /**
  505. * Module exports.
  506. */
  507. module.exports = exports = Socket;
  508. /**
  509. * Internal events (blacklisted).
  510. * These events can't be emitted by the user.
  511. *
  512. * @api private
  513. */
  514. var events = {
  515. connect: 1,
  516. connect_error: 1,
  517. connect_timeout: 1,
  518. disconnect: 1,
  519. error: 1,
  520. reconnect: 1,
  521. reconnect_attempt: 1,
  522. reconnect_failed: 1,
  523. reconnect_error: 1,
  524. reconnecting: 1
  525. };
  526. /**
  527. * Shortcut to `Emitter#emit`.
  528. */
  529. var emit = Emitter.prototype.emit;
  530. /**
  531. * `Socket` constructor.
  532. *
  533. * @api public
  534. */
  535. function Socket(io, nsp){
  536. this.io = io;
  537. this.nsp = nsp;
  538. this.json = this; // compat
  539. this.ids = 0;
  540. this.acks = {};
  541. if (this.io.autoConnect) this.open();
  542. this.receiveBuffer = [];
  543. this.sendBuffer = [];
  544. this.connected = false;
  545. this.disconnected = true;
  546. }
  547. /**
  548. * Mix in `Emitter`.
  549. */
  550. Emitter(Socket.prototype);
  551. /**
  552. * Subscribe to open, close and packet events
  553. *
  554. * @api private
  555. */
  556. Socket.prototype.subEvents = function() {
  557. if (this.subs) return;
  558. var io = this.io;
  559. this.subs = [
  560. on(io, 'open', bind(this, 'onopen')),
  561. on(io, 'packet', bind(this, 'onpacket')),
  562. on(io, 'close', bind(this, 'onclose'))
  563. ];
  564. };
  565. /**
  566. * "Opens" the socket.
  567. *
  568. * @api public
  569. */
  570. Socket.prototype.open =
  571. Socket.prototype.connect = function(){
  572. if (this.connected) return this;
  573. this.subEvents();
  574. this.io.open(); // ensure open
  575. if ('open' == this.io.readyState) this.onopen();
  576. return this;
  577. };
  578. /**
  579. * Sends a `message` event.
  580. *
  581. * @return {Socket} self
  582. * @api public
  583. */
  584. Socket.prototype.send = function(){
  585. var args = toArray(arguments);
  586. args.unshift('message');
  587. this.emit.apply(this, args);
  588. return this;
  589. };
  590. /**
  591. * Override `emit`.
  592. * If the event is in `events`, it's emitted normally.
  593. *
  594. * @param {String} event name
  595. * @return {Socket} self
  596. * @api public
  597. */
  598. Socket.prototype.emit = function(ev){
  599. if (events.hasOwnProperty(ev)) {
  600. emit.apply(this, arguments);
  601. return this;
  602. }
  603. var args = toArray(arguments);
  604. var parserType = parser.EVENT; // default
  605. if (hasBin(args)) { parserType = parser.BINARY_EVENT; } // binary
  606. var packet = { type: parserType, data: args };
  607. // event ack callback
  608. if ('function' == typeof args[args.length - 1]) {
  609. debug('emitting packet with ack id %d', this.ids);
  610. this.acks[this.ids] = args.pop();
  611. packet.id = this.ids++;
  612. }
  613. if (this.connected) {
  614. this.packet(packet);
  615. } else {
  616. this.sendBuffer.push(packet);
  617. }
  618. return this;
  619. };
  620. /**
  621. * Sends a packet.
  622. *
  623. * @param {Object} packet
  624. * @api private
  625. */
  626. Socket.prototype.packet = function(packet){
  627. packet.nsp = this.nsp;
  628. this.io.packet(packet);
  629. };
  630. /**
  631. * Called upon engine `open`.
  632. *
  633. * @api private
  634. */
  635. Socket.prototype.onopen = function(){
  636. debug('transport is open - connecting');
  637. // write connect packet if necessary
  638. if ('/' != this.nsp) {
  639. this.packet({ type: parser.CONNECT });
  640. }
  641. };
  642. /**
  643. * Called upon engine `close`.
  644. *
  645. * @param {String} reason
  646. * @api private
  647. */
  648. Socket.prototype.onclose = function(reason){
  649. debug('close (%s)', reason);
  650. this.connected = false;
  651. this.disconnected = true;
  652. this.emit('disconnect', reason);
  653. };
  654. /**
  655. * Called with socket packet.
  656. *
  657. * @param {Object} packet
  658. * @api private
  659. */
  660. Socket.prototype.onpacket = function(packet){
  661. if (packet.nsp != this.nsp) return;
  662. switch (packet.type) {
  663. case parser.CONNECT:
  664. this.onconnect();
  665. break;
  666. case parser.EVENT:
  667. this.onevent(packet);
  668. break;
  669. case parser.BINARY_EVENT:
  670. this.onevent(packet);
  671. break;
  672. case parser.ACK:
  673. this.onack(packet);
  674. break;
  675. case parser.BINARY_ACK:
  676. this.onack(packet);
  677. break;
  678. case parser.DISCONNECT:
  679. this.ondisconnect();
  680. break;
  681. case parser.ERROR:
  682. this.emit('error', packet.data);
  683. break;
  684. }
  685. };
  686. /**
  687. * Called upon a server event.
  688. *
  689. * @param {Object} packet
  690. * @api private
  691. */
  692. Socket.prototype.onevent = function(packet){
  693. var args = packet.data || [];
  694. debug('emitting event %j', args);
  695. if (null != packet.id) {
  696. debug('attaching ack callback to event');
  697. args.push(this.ack(packet.id));
  698. }
  699. if (this.connected) {
  700. emit.apply(this, args);
  701. } else {
  702. this.receiveBuffer.push(args);
  703. }
  704. };
  705. /**
  706. * Produces an ack callback to emit with an event.
  707. *
  708. * @api private
  709. */
  710. Socket.prototype.ack = function(id){
  711. var self = this;
  712. var sent = false;
  713. return function(){
  714. // prevent double callbacks
  715. if (sent) return;
  716. sent = true;
  717. var args = toArray(arguments);
  718. debug('sending ack %j', args);
  719. var type = hasBin(args) ? parser.BINARY_ACK : parser.ACK;
  720. self.packet({
  721. type: type,
  722. id: id,
  723. data: args
  724. });
  725. };
  726. };
  727. /**
  728. * Called upon a server acknowlegement.
  729. *
  730. * @param {Object} packet
  731. * @api private
  732. */
  733. Socket.prototype.onack = function(packet){
  734. debug('calling ack %s with %j', packet.id, packet.data);
  735. var fn = this.acks[packet.id];
  736. fn.apply(this, packet.data);
  737. delete this.acks[packet.id];
  738. };
  739. /**
  740. * Called upon server connect.
  741. *
  742. * @api private
  743. */
  744. Socket.prototype.onconnect = function(){
  745. this.connected = true;
  746. this.disconnected = false;
  747. this.emit('connect');
  748. this.emitBuffered();
  749. };
  750. /**
  751. * Emit buffered events (received and emitted).
  752. *
  753. * @api private
  754. */
  755. Socket.prototype.emitBuffered = function(){
  756. var i;
  757. for (i = 0; i < this.receiveBuffer.length; i++) {
  758. emit.apply(this, this.receiveBuffer[i]);
  759. }
  760. this.receiveBuffer = [];
  761. for (i = 0; i < this.sendBuffer.length; i++) {
  762. this.packet(this.sendBuffer[i]);
  763. }
  764. this.sendBuffer = [];
  765. };
  766. /**
  767. * Called upon server disconnect.
  768. *
  769. * @api private
  770. */
  771. Socket.prototype.ondisconnect = function(){
  772. debug('server disconnect (%s)', this.nsp);
  773. this.destroy();
  774. this.onclose('io server disconnect');
  775. };
  776. /**
  777. * Called upon forced client/server side disconnections,
  778. * this method ensures the manager stops tracking us and
  779. * that reconnections don't get triggered for this.
  780. *
  781. * @api private.
  782. */
  783. Socket.prototype.destroy = function(){
  784. if (this.subs) {
  785. // clean subscriptions to avoid reconnections
  786. for (var i = 0; i < this.subs.length; i++) {
  787. this.subs[i].destroy();
  788. }
  789. this.subs = null;
  790. }
  791. this.io.destroy(this);
  792. };
  793. /**
  794. * Disconnects the socket manually.
  795. *
  796. * @return {Socket} self
  797. * @api public
  798. */
  799. Socket.prototype.close =
  800. Socket.prototype.disconnect = function(){
  801. if (this.connected) {
  802. debug('performing disconnect (%s)', this.nsp);
  803. this.packet({ type: parser.DISCONNECT });
  804. }
  805. // remove socket from pool
  806. this.destroy();
  807. if (this.connected) {
  808. // fire events
  809. this.onclose('io client disconnect');
  810. }
  811. return this;
  812. };
  813. },{"./on":4,"component-bind":7,"component-emitter":8,"debug":9,"has-binary":32,"socket.io-parser":40,"to-array":44}],6:[function(_dereq_,module,exports){
  814. (function (global){
  815. /**
  816. * Module dependencies.
  817. */
  818. var parseuri = _dereq_('parseuri');
  819. var debug = _dereq_('debug')('socket.io-client:url');
  820. /**
  821. * Module exports.
  822. */
  823. module.exports = url;
  824. /**
  825. * URL parser.
  826. *
  827. * @param {String} url
  828. * @param {Object} An object meant to mimic window.location.
  829. * Defaults to window.location.
  830. * @api public
  831. */
  832. function url(uri, loc){
  833. var obj = uri;
  834. // default to window.location
  835. var loc = loc || global.location;
  836. if (null == uri) uri = loc.protocol + '//' + loc.hostname;
  837. // relative path support
  838. if ('string' == typeof uri) {
  839. if ('/' == uri.charAt(0)) {
  840. if ('/' == uri.charAt(1)) {
  841. uri = loc.protocol + uri;
  842. } else {
  843. uri = loc.hostname + uri;
  844. }
  845. }
  846. if (!/^(https?|wss?):\/\//.test(uri)) {
  847. debug('protocol-less url %s', uri);
  848. if ('undefined' != typeof loc) {
  849. uri = loc.protocol + '//' + uri;
  850. } else {
  851. uri = 'https://' + uri;
  852. }
  853. }
  854. // parse
  855. debug('parse %s', uri);
  856. obj = parseuri(uri);
  857. }
  858. // make sure we treat `localhost:80` and `localhost` equally
  859. if (!obj.port) {
  860. if (/^(http|ws)$/.test(obj.protocol)) {
  861. obj.port = '80';
  862. }
  863. else if (/^(http|ws)s$/.test(obj.protocol)) {
  864. obj.port = '443';
  865. }
  866. }
  867. obj.path = obj.path || '/';
  868. // define unique id
  869. obj.id = obj.protocol + '://' + obj.host + ':' + obj.port;
  870. // define href
  871. obj.href = obj.protocol + '://' + obj.host + (loc && loc.port == obj.port ? '' : (':' + obj.port));
  872. return obj;
  873. }
  874. }).call(this,typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
  875. },{"debug":9,"parseuri":38}],7:[function(_dereq_,module,exports){
  876. /**
  877. * Slice reference.
  878. */
  879. var slice = [].slice;
  880. /**
  881. * Bind `obj` to `fn`.
  882. *
  883. * @param {Object} obj
  884. * @param {Function|String} fn or string
  885. * @return {Function}
  886. * @api public
  887. */
  888. module.exports = function(obj, fn){
  889. if ('string' == typeof fn) fn = obj[fn];
  890. if ('function' != typeof fn) throw new Error('bind() requires a function');
  891. var args = slice.call(arguments, 2);
  892. return function(){
  893. return fn.apply(obj, args.concat(slice.call(arguments)));
  894. }
  895. };
  896. },{}],8:[function(_dereq_,module,exports){
  897. /**
  898. * Expose `Emitter`.
  899. */
  900. module.exports = Emitter;
  901. /**
  902. * Initialize a new `Emitter`.
  903. *
  904. * @api public
  905. */
  906. function Emitter(obj) {
  907. if (obj) return mixin(obj);
  908. };
  909. /**
  910. * Mixin the emitter properties.
  911. *
  912. * @param {Object} obj
  913. * @return {Object}
  914. * @api private
  915. */
  916. function mixin(obj) {
  917. for (var key in Emitter.prototype) {
  918. obj[key] = Emitter.prototype[key];
  919. }
  920. return obj;
  921. }
  922. /**
  923. * Listen on the given `event` with `fn`.
  924. *
  925. * @param {String} event
  926. * @param {Function} fn
  927. * @return {Emitter}
  928. * @api public
  929. */
  930. Emitter.prototype.on =
  931. Emitter.prototype.addEventListener = function(event, fn){
  932. this._callbacks = this._callbacks || {};
  933. (this._callbacks[event] = this._callbacks[event] || [])
  934. .push(fn);
  935. return this;
  936. };
  937. /**
  938. * Adds an `event` listener that will be invoked a single
  939. * time then automatically removed.
  940. *
  941. * @param {String} event
  942. * @param {Function} fn
  943. * @return {Emitter}
  944. * @api public
  945. */
  946. Emitter.prototype.once = function(event, fn){
  947. var self = this;
  948. this._callbacks = this._callbacks || {};
  949. function on() {
  950. self.off(event, on);
  951. fn.apply(this, arguments);
  952. }
  953. on.fn = fn;
  954. this.on(event, on);
  955. return this;
  956. };
  957. /**
  958. * Remove the given callback for `event` or all
  959. * registered callbacks.
  960. *
  961. * @param {String} event
  962. * @param {Function} fn
  963. * @return {Emitter}
  964. * @api public
  965. */
  966. Emitter.prototype.off =
  967. Emitter.prototype.removeListener =
  968. Emitter.prototype.removeAllListeners =
  969. Emitter.prototype.removeEventListener = function(event, fn){
  970. this._callbacks = this._callbacks || {};
  971. // all
  972. if (0 == arguments.length) {
  973. this._callbacks = {};
  974. return this;
  975. }
  976. // specific event
  977. var callbacks = this._callbacks[event];
  978. if (!callbacks) return this;
  979. // remove all handlers
  980. if (1 == arguments.length) {
  981. delete this._callbacks[event];
  982. return this;
  983. }
  984. // remove specific handler
  985. var cb;
  986. for (var i = 0; i < callbacks.length; i++) {
  987. cb = callbacks[i];
  988. if (cb === fn || cb.fn === fn) {
  989. callbacks.splice(i, 1);
  990. break;
  991. }
  992. }
  993. return this;
  994. };
  995. /**
  996. * Emit `event` with the given args.
  997. *
  998. * @param {String} event
  999. * @param {Mixed} ...
  1000. * @return {Emitter}
  1001. */
  1002. Emitter.prototype.emit = function(event){
  1003. this._callbacks = this._callbacks || {};
  1004. var args = [].slice.call(arguments, 1)
  1005. , callbacks = this._callbacks[event];
  1006. if (callbacks) {
  1007. callbacks = callbacks.slice(0);
  1008. for (var i = 0, len = callbacks.length; i < len; ++i) {
  1009. callbacks[i].apply(this, args);
  1010. }
  1011. }
  1012. return this;
  1013. };
  1014. /**
  1015. * Return array of callbacks for `event`.
  1016. *
  1017. * @param {String} event
  1018. * @return {Array}
  1019. * @api public
  1020. */
  1021. Emitter.prototype.listeners = function(event){
  1022. this._callbacks = this._callbacks || {};
  1023. return this._callbacks[event] || [];
  1024. };
  1025. /**
  1026. * Check if this emitter has `event` handlers.
  1027. *
  1028. * @param {String} event
  1029. * @return {Boolean}
  1030. * @api public
  1031. */
  1032. Emitter.prototype.hasListeners = function(event){
  1033. return !! this.listeners(event).length;
  1034. };
  1035. },{}],9:[function(_dereq_,module,exports){
  1036. /**
  1037. * Expose `debug()` as the module.
  1038. */
  1039. module.exports = debug;
  1040. /**
  1041. * Create a debugger with the given `name`.
  1042. *
  1043. * @param {String} name
  1044. * @return {Type}
  1045. * @api public
  1046. */
  1047. function debug(name) {
  1048. if (!debug.enabled(name)) return function(){};
  1049. return function(fmt){
  1050. fmt = coerce(fmt);
  1051. var curr = new Date;
  1052. var ms = curr - (debug[name] || curr);
  1053. debug[name] = curr;
  1054. fmt = name
  1055. + ' '
  1056. + fmt
  1057. + ' +' + debug.humanize(ms);
  1058. // This hackery is required for IE8
  1059. // where `console.log` doesn't have 'apply'
  1060. window.console
  1061. && console.log
  1062. && Function.prototype.apply.call(console.log, console, arguments);
  1063. }
  1064. }
  1065. /**
  1066. * The currently active debug mode names.
  1067. */
  1068. debug.names = [];
  1069. debug.skips = [];
  1070. /**
  1071. * Enables a debug mode by name. This can include modes
  1072. * separated by a colon and wildcards.
  1073. *
  1074. * @param {String} name
  1075. * @api public
  1076. */
  1077. debug.enable = function(name) {
  1078. try {
  1079. localStorage.debug = name;
  1080. } catch(e){}
  1081. var split = (name || '').split(/[\s,]+/)
  1082. , len = split.length;
  1083. for (var i = 0; i < len; i++) {
  1084. name = split[i].replace('*', '.*?');
  1085. if (name[0] === '-') {
  1086. debug.skips.push(new RegExp('^' + name.substr(1) + '$'));
  1087. }
  1088. else {
  1089. debug.names.push(new RegExp('^' + name + '$'));
  1090. }
  1091. }
  1092. };
  1093. /**
  1094. * Disable debug output.
  1095. *
  1096. * @api public
  1097. */
  1098. debug.disable = function(){
  1099. debug.enable('');
  1100. };
  1101. /**
  1102. * Humanize the given `ms`.
  1103. *
  1104. * @param {Number} m
  1105. * @return {String}
  1106. * @api private
  1107. */
  1108. debug.humanize = function(ms) {
  1109. var sec = 1000
  1110. , min = 60 * 1000
  1111. , hour = 60 * min;
  1112. if (ms >= hour) return (ms / hour).toFixed(1) + 'h';
  1113. if (ms >= min) return (ms / min).toFixed(1) + 'm';
  1114. if (ms >= sec) return (ms / sec | 0) + 's';
  1115. return ms + 'ms';
  1116. };
  1117. /**
  1118. * Returns true if the given mode name is enabled, false otherwise.
  1119. *
  1120. * @param {String} name
  1121. * @return {Boolean}
  1122. * @api public
  1123. */
  1124. debug.enabled = function(name) {
  1125. for (var i = 0, len = debug.skips.length; i < len; i++) {
  1126. if (debug.skips[i].test(name)) {
  1127. return false;
  1128. }
  1129. }
  1130. for (var i = 0, len = debug.names.length; i < len; i++) {
  1131. if (debug.names[i].test(name)) {
  1132. return true;
  1133. }
  1134. }
  1135. return false;
  1136. };
  1137. /**
  1138. * Coerce `val`.
  1139. */
  1140. function coerce(val) {
  1141. if (val instanceof Error) return val.stack || val.message;
  1142. return val;
  1143. }
  1144. // persist
  1145. try {
  1146. if (window.localStorage) debug.enable(localStorage.debug);
  1147. } catch(e){}
  1148. },{}],10:[function(_dereq_,module,exports){
  1149. module.exports = _dereq_('./lib/');
  1150. },{"./lib/":11}],11:[function(_dereq_,module,exports){
  1151. module.exports = _dereq_('./socket');
  1152. /**
  1153. * Exports parser
  1154. *
  1155. * @api public
  1156. *
  1157. */
  1158. module.exports.parser = _dereq_('engine.io-parser');
  1159. },{"./socket":12,"engine.io-parser":21}],12:[function(_dereq_,module,exports){
  1160. (function (global){
  1161. /**
  1162. * Module dependencies.
  1163. */
  1164. var transports = _dereq_('./transports');
  1165. var Emitter = _dereq_('component-emitter');
  1166. var debug = _dereq_('debug')('engine.io-client:socket');
  1167. var index = _dereq_('indexof');
  1168. var parser = _dereq_('engine.io-parser');
  1169. var parseuri = _dereq_('parseuri');
  1170. var parsejson = _dereq_('parsejson');
  1171. var parseqs = _dereq_('parseqs');
  1172. /**
  1173. * Module exports.
  1174. */
  1175. module.exports = Socket;
  1176. /**
  1177. * Noop function.
  1178. *
  1179. * @api private
  1180. */
  1181. function noop(){}
  1182. /**
  1183. * Socket constructor.
  1184. *
  1185. * @param {String|Object} uri or options
  1186. * @param {Object} options
  1187. * @api public
  1188. */
  1189. function Socket(uri, opts){
  1190. if (!(this instanceof Socket)) return new Socket(uri, opts);
  1191. opts = opts || {};
  1192. if (uri && 'object' == typeof uri) {
  1193. opts = uri;
  1194. uri = null;
  1195. }
  1196. if (uri) {
  1197. uri = parseuri(uri);
  1198. opts.host = uri.host;
  1199. opts.secure = uri.protocol == 'https' || uri.protocol == 'wss';
  1200. opts.port = uri.port;
  1201. if (uri.query) opts.query = uri.query;
  1202. }
  1203. this.secure = null != opts.secure ? opts.secure :
  1204. (global.location && 'https:' == location.protocol);
  1205. if (opts.host) {
  1206. var pieces = opts.host.split(':');
  1207. opts.hostname = pieces.shift();
  1208. if (pieces.length) opts.port = pieces.pop();
  1209. }
  1210. this.agent = opts.agent || false;
  1211. this.hostname = opts.hostname ||
  1212. (global.location ? location.hostname : 'localhost');
  1213. this.port = opts.port || (global.location && location.port ?
  1214. location.port :
  1215. (this.secure ? 443 : 80));
  1216. this.query = opts.query || {};
  1217. if ('string' == typeof this.query) this.query = parseqs.decode(this.query);
  1218. this.upgrade = false !== opts.upgrade;
  1219. this.path = (opts.path || '/engine.io').replace(/\/$/, '') + '/';
  1220. this.forceJSONP = !!opts.forceJSONP;
  1221. this.jsonp = false !== opts.jsonp;
  1222. this.forceBase64 = !!opts.forceBase64;
  1223. this.enablesXDR = !!opts.enablesXDR;
  1224. this.timestampParam = opts.timestampParam || 't';
  1225. this.timestampRequests = opts.timestampRequests;
  1226. this.transports = opts.transports || ['polling', 'websocket'];
  1227. this.readyState = '';
  1228. this.writeBuffer = [];
  1229. this.callbackBuffer = [];
  1230. this.policyPort = opts.policyPort || 843;
  1231. this.rememberUpgrade = opts.rememberUpgrade || false;
  1232. this.open();
  1233. this.binaryType = null;
  1234. this.onlyBinaryUpgrades = opts.onlyBinaryUpgrades;
  1235. }
  1236. Socket.priorWebsocketSuccess = false;
  1237. /**
  1238. * Mix in `Emitter`.
  1239. */
  1240. Emitter(Socket.prototype);
  1241. /**
  1242. * Protocol version.
  1243. *
  1244. * @api public
  1245. */
  1246. Socket.protocol = parser.protocol; // this is an int
  1247. /**
  1248. * Expose deps for legacy compatibility
  1249. * and standalone browser access.
  1250. */
  1251. Socket.Socket = Socket;
  1252. Socket.Transport = _dereq_('./transport');
  1253. Socket.transports = _dereq_('./transports');
  1254. Socket.parser = _dereq_('engine.io-parser');
  1255. /**
  1256. * Creates transport of the given type.
  1257. *
  1258. * @param {String} transport name
  1259. * @return {Transport}
  1260. * @api private
  1261. */
  1262. Socket.prototype.createTransport = function (name) {
  1263. debug('creating transport "%s"', name);
  1264. var query = clone(this.query);
  1265. // append engine.io protocol identifier
  1266. query.EIO = parser.protocol;
  1267. // transport name
  1268. query.transport = name;
  1269. // session id if we already have one
  1270. if (this.id) query.sid = this.id;
  1271. var transport = new transports[name]({
  1272. agent: this.agent,
  1273. hostname: this.hostname,
  1274. port: this.port,
  1275. secure: this.secure,
  1276. path: this.path,
  1277. query: query,
  1278. forceJSONP: this.forceJSONP,
  1279. jsonp: this.jsonp,
  1280. forceBase64: this.forceBase64,
  1281. enablesXDR: this.enablesXDR,
  1282. timestampRequests: this.timestampRequests,
  1283. timestampParam: this.timestampParam,
  1284. policyPort: this.policyPort,
  1285. socket: this
  1286. });
  1287. return transport;
  1288. };
  1289. function clone (obj) {
  1290. var o = {};
  1291. for (var i in obj) {
  1292. if (obj.hasOwnProperty(i)) {
  1293. o[i] = obj[i];
  1294. }
  1295. }
  1296. return o;
  1297. }
  1298. /**
  1299. * Initializes transport to use and starts probe.
  1300. *
  1301. * @api private
  1302. */
  1303. Socket.prototype.open = function () {
  1304. var transport;
  1305. if (this.rememberUpgrade && Socket.priorWebsocketSuccess && this.transports.indexOf('websocket') != -1) {
  1306. transport = 'websocket';
  1307. } else if (0 == this.transports.length) {
  1308. // Emit error on next tick so it can be listened to
  1309. var self = this;
  1310. setTimeout(function() {
  1311. self.emit('error', 'No transports available');
  1312. }, 0);
  1313. return;
  1314. } else {
  1315. transport = this.transports[0];
  1316. }
  1317. this.readyState = 'opening';
  1318. // Retry with the next transport if the transport is disabled (jsonp: false)
  1319. var transport;
  1320. try {
  1321. transport = this.createTransport(transport);
  1322. } catch (e) {
  1323. this.transports.shift();
  1324. this.open();
  1325. return;
  1326. }
  1327. transport.open();
  1328. this.setTransport(transport);
  1329. };
  1330. /**
  1331. * Sets the current transport. Disables the existing one (if any).
  1332. *
  1333. * @api private
  1334. */
  1335. Socket.prototype.setTransport = function(transport){
  1336. debug('setting transport %s', transport.name);
  1337. var self = this;
  1338. if (this.transport) {
  1339. debug('clearing existing transport %s', this.transport.name);
  1340. this.transport.removeAllListeners();
  1341. }
  1342. // set up transport
  1343. this.transport = transport;
  1344. // set up transport listeners
  1345. transport
  1346. .on('drain', function(){
  1347. self.onDrain();
  1348. })
  1349. .on('packet', function(packet){
  1350. self.onPacket(packet);
  1351. })
  1352. .on('error', function(e){
  1353. self.onError(e);
  1354. })
  1355. .on('close', function(){
  1356. self.onClose('transport close');
  1357. });
  1358. };
  1359. /**
  1360. * Probes a transport.
  1361. *
  1362. * @param {String} transport name
  1363. * @api private
  1364. */
  1365. Socket.prototype.probe = function (name) {
  1366. debug('probing transport "%s"', name);
  1367. var transport = this.createTransport(name, { probe: 1 })
  1368. , failed = false
  1369. , self = this;
  1370. Socket.priorWebsocketSuccess = false;
  1371. function onTransportOpen(){
  1372. if (self.onlyBinaryUpgrades) {
  1373. var upgradeLosesBinary = !this.supportsBinary && self.transport.supportsBinary;
  1374. failed = failed || upgradeLosesBinary;
  1375. }
  1376. if (failed) return;
  1377. debug('probe transport "%s" opened', name);
  1378. transport.send([{ type: 'ping', data: 'probe' }]);
  1379. transport.once('packet', function (msg) {
  1380. if (failed) return;
  1381. if ('pong' == msg.type && 'probe' == msg.data) {
  1382. debug('probe transport "%s" pong', name);
  1383. self.upgrading = true;
  1384. self.emit('upgrading', transport);
  1385. if (!transport) return;
  1386. Socket.priorWebsocketSuccess = 'websocket' == transport.name;
  1387. debug('pausing current transport "%s"', self.transport.name);
  1388. self.transport.pause(function () {
  1389. if (failed) return;
  1390. if ('closed' == self.readyState) return;
  1391. debug('changing transport and sending upgrade packet');
  1392. cleanup();
  1393. self.setTransport(transport);
  1394. transport.send([{ type: 'upgrade' }]);
  1395. self.emit('upgrade', transport);
  1396. transport = null;
  1397. self.upgrading = false;
  1398. self.flush();
  1399. });
  1400. } else {
  1401. debug('probe transport "%s" failed', name);
  1402. var err = new Error('probe error');
  1403. err.transport = transport.name;
  1404. self.emit('upgradeError', err);
  1405. }
  1406. });
  1407. }
  1408. function freezeTransport() {
  1409. if (failed) return;
  1410. // Any callback called by transport should be ignored since now
  1411. failed = true;
  1412. cleanup();
  1413. transport.close();
  1414. transport = null;
  1415. }
  1416. //Handle any error that happens while probing
  1417. function onerror(err) {
  1418. var error = new Error('probe error: ' + err);
  1419. error.transport = transport.name;
  1420. freezeTransport();
  1421. debug('probe transport "%s" failed because of error: %s', name, err);
  1422. self.emit('upgradeError', error);
  1423. }
  1424. function onTransportClose(){
  1425. onerror("transport closed");
  1426. }
  1427. //When the socket is closed while we're probing
  1428. function onclose(){
  1429. onerror("socket closed");
  1430. }
  1431. //When the socket is upgraded while we're probing
  1432. function onupgrade(to){
  1433. if (transport && to.name != transport.name) {
  1434. debug('"%s" works - aborting "%s"', to.name, transport.name);
  1435. freezeTransport();
  1436. }
  1437. }
  1438. //Remove all listeners on the transport and on self
  1439. function cleanup(){
  1440. transport.removeListener('open', onTransportOpen);
  1441. transport.removeListener('error', onerror);
  1442. transport.removeListener('close', onTransportClose);
  1443. self.removeListener('close', onclose);
  1444. self.removeListener('upgrading', onupgrade);
  1445. }
  1446. transport.once('open', onTransportOpen);
  1447. transport.once('error', onerror);
  1448. transport.once('close', onTransportClose);
  1449. this.once('close', onclose);
  1450. this.once('upgrading', onupgrade);
  1451. transport.open();
  1452. };
  1453. /**
  1454. * Called when connection is deemed open.
  1455. *
  1456. * @api public
  1457. */
  1458. Socket.prototype.onOpen = function () {
  1459. debug('socket open');
  1460. this.readyState = 'open';
  1461. Socket.priorWebsocketSuccess = 'websocket' == this.transport.name;
  1462. this.emit('open');
  1463. this.flush();
  1464. // we check for `readyState` in case an `open`
  1465. // listener already closed the socket
  1466. if ('open' == this.readyState && this.upgrade && this.transport.pause) {
  1467. debug('starting upgrade probes');
  1468. for (var i = 0, l = this.upgrades.length; i < l; i++) {
  1469. this.probe(this.upgrades[i]);
  1470. }
  1471. }
  1472. };
  1473. /**
  1474. * Handles a packet.
  1475. *
  1476. * @api private
  1477. */
  1478. Socket.prototype.onPacket = function (packet) {
  1479. if ('opening' == this.readyState || 'open' == this.readyState) {
  1480. debug('socket receive: type "%s", data "%s"', packet.type, packet.data);
  1481. this.emit('packet', packet);
  1482. // Socket is live - any packet counts
  1483. this.emit('heartbeat');
  1484. switch (packet.type) {
  1485. case 'open':
  1486. this.onHandshake(parsejson(packet.data));
  1487. break;
  1488. case 'pong':
  1489. this.setPing();
  1490. break;
  1491. case 'error':
  1492. var err = new Error('server error');
  1493. err.code = packet.data;
  1494. this.emit('error', err);
  1495. break;
  1496. case 'message':
  1497. this.emit('data', packet.data);
  1498. this.emit('message', packet.data);
  1499. break;
  1500. }
  1501. } else {
  1502. debug('packet received with socket readyState "%s"', this.readyState);
  1503. }
  1504. };
  1505. /**
  1506. * Called upon handshake completion.
  1507. *
  1508. * @param {Object} handshake obj
  1509. * @api private
  1510. */
  1511. Socket.prototype.onHandshake = function (data) {
  1512. this.emit('handshake', data);
  1513. this.id = data.sid;
  1514. this.transport.query.sid = data.sid;
  1515. this.upgrades = this.filterUpgrades(data.upgrades);
  1516. this.pingInterval = data.pingInterval;
  1517. this.pingTimeout = data.pingTimeout;
  1518. this.onOpen();
  1519. // In case open handler closes socket
  1520. if ('closed' == this.readyState) return;
  1521. this.setPing();
  1522. // Prolong liveness of socket on heartbeat
  1523. this.removeListener('heartbeat', this.onHeartbeat);
  1524. this.on('heartbeat', this.onHeartbeat);
  1525. };
  1526. /**
  1527. * Resets ping timeout.
  1528. *
  1529. * @api private
  1530. */
  1531. Socket.prototype.onHeartbeat = function (timeout) {
  1532. clearTimeout(this.pingTimeoutTimer);
  1533. var self = this;
  1534. self.pingTimeoutTimer = setTimeout(function () {
  1535. if ('closed' == self.readyState) return;
  1536. self.onClose('ping timeout');
  1537. }, timeout || (self.pingInterval + self.pingTimeout));
  1538. };
  1539. /**
  1540. * Pings server every `this.pingInterval` and expects response
  1541. * within `this.pingTimeout` or closes connection.
  1542. *
  1543. * @api private
  1544. */
  1545. Socket.prototype.setPing = function () {
  1546. var self = this;
  1547. clearTimeout(self.pingIntervalTimer);
  1548. self.pingIntervalTimer = setTimeout(function () {
  1549. debug('writing ping packet - expecting pong within %sms', self.pingTimeout);
  1550. self.ping();
  1551. self.onHeartbeat(self.pingTimeout);
  1552. }, self.pingInterval);
  1553. };
  1554. /**
  1555. * Sends a ping packet.
  1556. *
  1557. * @api public
  1558. */
  1559. Socket.prototype.ping = function () {
  1560. this.sendPacket('ping');
  1561. };
  1562. /**
  1563. * Called on `drain` event
  1564. *
  1565. * @api private
  1566. */
  1567. Socket.prototype.onDrain = function() {
  1568. for (var i = 0; i < this.prevBufferLen; i++) {
  1569. if (this.callbackBuffer[i]) {
  1570. this.callbackBuffer[i]();
  1571. }
  1572. }
  1573. this.writeBuffer.splice(0, this.prevBufferLen);
  1574. this.callbackBuffer.splice(0, this.prevBufferLen);
  1575. // setting prevBufferLen = 0 is very important
  1576. // for example, when upgrading, upgrade packet is sent over,
  1577. // and a nonzero prevBufferLen could cause problems on `drain`
  1578. this.prevBufferLen = 0;
  1579. if (this.writeBuffer.length == 0) {
  1580. this.emit('drain');
  1581. } else {
  1582. this.flush();
  1583. }
  1584. };
  1585. /**
  1586. * Flush write buffers.
  1587. *
  1588. * @api private
  1589. */
  1590. Socket.prototype.flush = function () {
  1591. if ('closed' != this.readyState && this.transport.writable &&
  1592. !this.upgrading && this.writeBuffer.length) {
  1593. debug('flushing %d packets in socket', this.writeBuffer.length);
  1594. this.transport.send(this.writeBuffer);
  1595. // keep track of current length of writeBuffer
  1596. // splice writeBuffer and callbackBuffer on `drain`
  1597. this.prevBufferLen = this.writeBuffer.length;
  1598. this.emit('flush');
  1599. }
  1600. };
  1601. /**
  1602. * Sends a message.
  1603. *
  1604. * @param {String} message.
  1605. * @param {Function} callback function.
  1606. * @return {Socket} for chaining.
  1607. * @api public
  1608. */
  1609. Socket.prototype.write =
  1610. Socket.prototype.send = function (msg, fn) {
  1611. this.sendPacket('message', msg, fn);
  1612. return this;
  1613. };
  1614. /**
  1615. * Sends a packet.
  1616. *
  1617. * @param {String} packet type.
  1618. * @param {String} data.
  1619. * @param {Function} callback function.
  1620. * @api private
  1621. */
  1622. Socket.prototype.sendPacket = function (type, data, fn) {
  1623. if ('closing' == this.readyState || 'closed' == this.readyState) {
  1624. return;
  1625. }
  1626. var packet = { type: type, data: data };
  1627. this.emit('packetCreate', packet);
  1628. this.writeBuffer.push(packet);
  1629. this.callbackBuffer.push(fn);
  1630. this.flush();
  1631. };
  1632. /**
  1633. * Closes the connection.
  1634. *
  1635. * @api private
  1636. */
  1637. Socket.prototype.close = function () {
  1638. if ('opening' == this.readyState || 'open' == this.readyState) {
  1639. this.readyState = 'closing';
  1640. var self = this;
  1641. function close() {
  1642. self.onClose('forced close');
  1643. debug('socket closing - telling transport to close');
  1644. self.transport.close();
  1645. }
  1646. function cleanupAndClose() {
  1647. self.removeListener('upgrade', cleanupAndClose);
  1648. self.removeListener('upgradeError', cleanupAndClose);
  1649. close();
  1650. }
  1651. function waitForUpgrade() {
  1652. // wait for upgrade to finish since we can't send packets while pausing a transport
  1653. self.once('upgrade', cleanupAndClose);
  1654. self.once('upgradeError', cleanupAndClose);
  1655. }
  1656. if (this.writeBuffer.length) {
  1657. this.once('drain', function() {
  1658. if (this.upgrading) {
  1659. waitForUpgrade();
  1660. } else {
  1661. close();
  1662. }
  1663. });
  1664. } else if (this.upgrading) {
  1665. waitForUpgrade();
  1666. } else {
  1667. close();
  1668. }
  1669. }
  1670. return this;
  1671. };
  1672. /**
  1673. * Called upon transport error
  1674. *
  1675. * @api private
  1676. */
  1677. Socket.prototype.onError = function (err) {
  1678. debug('socket error %j', err);
  1679. Socket.priorWebsocketSuccess = false;
  1680. this.emit('error', err);
  1681. this.onClose('transport error', err);
  1682. };
  1683. /**
  1684. * Called upon transport close.
  1685. *
  1686. * @api private
  1687. */
  1688. Socket.prototype.onClose = function (reason, desc) {
  1689. if ('opening' == this.readyState || 'open' == this.readyState || 'closing' == this.readyState) {
  1690. debug('socket close with reason: "%s"', reason);
  1691. var self = this;
  1692. // clear timers
  1693. clearTimeout(this.pingIntervalTimer);
  1694. clearTimeout(this.pingTimeoutTimer);
  1695. // clean buffers in next tick, so developers can still
  1696. // grab the buffers on `close` event
  1697. setTimeout(function() {
  1698. self.writeBuffer = [];
  1699. self.callbackBuffer = [];
  1700. self.prevBufferLen = 0;
  1701. }, 0);
  1702. // stop event from firing again for transport
  1703. this.transport.removeAllListeners('close');
  1704. // ensure transport won't stay open
  1705. this.transport.close();
  1706. // ignore further transport communication
  1707. this.transport.removeAllListeners();
  1708. // set ready state
  1709. this.readyState = 'closed';
  1710. // clear session id
  1711. this.id = null;
  1712. // emit close event
  1713. this.emit('close', reason, desc);
  1714. }
  1715. };
  1716. /**
  1717. * Filters upgrades, returning only those matching client transports.
  1718. *
  1719. * @param {Array} server upgrades
  1720. * @api private
  1721. *
  1722. */
  1723. Socket.prototype.filterUpgrades = function (upgrades) {
  1724. var filteredUpgrades = [];
  1725. for (var i = 0, j = upgrades.length; i<j; i++) {
  1726. if (~index(this.transports, upgrades[i])) filteredUpgrades.push(upgrades[i]);
  1727. }
  1728. return filteredUpgrades;
  1729. };
  1730. }).call(this,typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
  1731. },{"./transport":13,"./transports":14,"component-emitter":8,"debug":9,"engine.io-parser":21,"indexof":36,"parsejson":28,"parseqs":29,"parseuri":30}],13:[function(_dereq_,module,exports){
  1732. /**
  1733. * Module dependencies.
  1734. */
  1735. var parser = _dereq_('engine.io-parser');
  1736. var Emitter = _dereq_('component-emitter');
  1737. /**
  1738. * Module exports.
  1739. */
  1740. module.exports = Transport;
  1741. /**
  1742. * Transport abstract constructor.
  1743. *
  1744. * @param {Object} options.
  1745. * @api private
  1746. */
  1747. function Transport (opts) {
  1748. this.path = opts.path;
  1749. this.hostname = opts.hostname;
  1750. this.port = opts.port;
  1751. this.secure = opts.secure;
  1752. this.query = opts.query;
  1753. this.timestampParam = opts.timestampParam;
  1754. this.timestampRequests = opts.timestampRequests;
  1755. this.readyState = '';
  1756. this.agent = opts.agent || false;
  1757. this.socket = opts.socket;
  1758. this.enablesXDR = opts.enablesXDR;
  1759. }
  1760. /**
  1761. * Mix in `Emitter`.
  1762. */
  1763. Emitter(Transport.prototype);
  1764. /**
  1765. * A counter used to prevent collisions in the timestamps used
  1766. * for cache busting.
  1767. */
  1768. Transport.timestamps = 0;
  1769. /**
  1770. * Emits an error.
  1771. *
  1772. * @param {String} str
  1773. * @return {Transport} for chaining
  1774. * @api public
  1775. */
  1776. Transport.prototype.onError = function (msg, desc) {
  1777. var err = new Error(msg);
  1778. err.type = 'TransportError';
  1779. err.description = desc;
  1780. this.emit('error', err);
  1781. return this;
  1782. };
  1783. /**
  1784. * Opens the transport.
  1785. *
  1786. * @api public
  1787. */
  1788. Transport.prototype.open = function () {
  1789. if ('closed' == this.readyState || '' == this.readyState) {
  1790. this.readyState = 'opening';
  1791. this.doOpen();
  1792. }
  1793. return this;
  1794. };
  1795. /**
  1796. * Closes the transport.
  1797. *
  1798. * @api private
  1799. */
  1800. Transport.prototype.close = function () {
  1801. if ('opening' == this.readyState || 'open' == this.readyState) {
  1802. this.doClose();
  1803. this.onClose();
  1804. }
  1805. return this;
  1806. };
  1807. /**
  1808. * Sends multiple packets.
  1809. *
  1810. * @param {Array} packets
  1811. * @api private
  1812. */
  1813. Transport.prototype.send = function(packets){
  1814. if ('open' == this.readyState) {
  1815. this.write(packets);
  1816. } else {
  1817. throw new Error('Transport not open');
  1818. }
  1819. };
  1820. /**
  1821. * Called upon open
  1822. *
  1823. * @api private
  1824. */
  1825. Transport.prototype.onOpen = function () {
  1826. this.readyState = 'open';
  1827. this.writable = true;
  1828. this.emit('open');
  1829. };
  1830. /**
  1831. * Called with data.
  1832. *
  1833. * @param {String} data
  1834. * @api private
  1835. */
  1836. Transport.prototype.onData = function(data){
  1837. var packet = parser.decodePacket(data, this.socket.binaryType);
  1838. this.onPacket(packet);
  1839. };
  1840. /**
  1841. * Called with a decoded packet.
  1842. */
  1843. Transport.prototype.onPacket = function (packet) {
  1844. this.emit('packet', packet);
  1845. };
  1846. /**
  1847. * Called upon close.
  1848. *
  1849. * @api private
  1850. */
  1851. Transport.prototype.onClose = function () {
  1852. this.readyState = 'closed';
  1853. this.emit('close');
  1854. };
  1855. },{"component-emitter":8,"engine.io-parser":21}],14:[function(_dereq_,module,exports){
  1856. (function (global){
  1857. /**
  1858. * Module dependencies
  1859. */
  1860. var XMLHttpRequest = _dereq_('xmlhttprequest');
  1861. var XHR = _dereq_('./polling-xhr');
  1862. var JSONP = _dereq_('./polling-jsonp');
  1863. var websocket = _dereq_('./websocket');
  1864. /**
  1865. * Export transports.
  1866. */
  1867. exports.polling = polling;
  1868. exports.websocket = websocket;
  1869. /**
  1870. * Polling transport polymorphic constructor.
  1871. * Decides on xhr vs jsonp based on feature detection.
  1872. *
  1873. * @api private
  1874. */
  1875. function polling(opts){
  1876. var xhr;
  1877. var xd = false;
  1878. var xs = false;
  1879. var jsonp = false !== opts.jsonp;
  1880. if (global.location) {
  1881. var isSSL = 'https:' == location.protocol;
  1882. var port = location.port;
  1883. // some user agents have empty `location.port`
  1884. if (!port) {
  1885. port = isSSL ? 443 : 80;
  1886. }
  1887. xd = opts.hostname != location.hostname || port != opts.port;
  1888. xs = opts.secure != isSSL;
  1889. }
  1890. opts.xdomain = xd;
  1891. opts.xscheme = xs;
  1892. xhr = new XMLHttpRequest(opts);
  1893. if ('open' in xhr && !opts.forceJSONP) {
  1894. return new XHR(opts);
  1895. } else {
  1896. if (!jsonp) throw new Error('JSONP disabled');
  1897. return new JSONP(opts);
  1898. }
  1899. }
  1900. }).call(this,typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
  1901. },{"./polling-jsonp":15,"./polling-xhr":16,"./websocket":18,"xmlhttprequest":19}],15:[function(_dereq_,module,exports){
  1902. (function (global){
  1903. /**
  1904. * Module requirements.
  1905. */
  1906. var Polling = _dereq_('./polling');
  1907. var inherit = _dereq_('component-inherit');
  1908. /**
  1909. * Module exports.
  1910. */
  1911. module.exports = JSONPPolling;
  1912. /**
  1913. * Cached regular expressions.
  1914. */
  1915. var rNewline = /\n/g;
  1916. var rEscapedNewline = /\\n/g;
  1917. /**
  1918. * Global JSONP callbacks.
  1919. */
  1920. var callbacks;
  1921. /**
  1922. * Callbacks count.
  1923. */
  1924. var index = 0;
  1925. /**
  1926. * Noop.
  1927. */
  1928. function empty () { }
  1929. /**
  1930. * JSONP Polling constructor.
  1931. *
  1932. * @param {Object} opts.
  1933. * @api public
  1934. */
  1935. function JSONPPolling (opts) {
  1936. Polling.call(this, opts);
  1937. this.query = this.query || {};
  1938. // define global callbacks array if not present
  1939. // we do this here (lazily) to avoid unneeded global pollution
  1940. if (!callbacks) {
  1941. // we need to consider multiple engines in the same page
  1942. if (!global.___eio) global.___eio = [];
  1943. callbacks = global.___eio;
  1944. }
  1945. // callback identifier
  1946. this.index = callbacks.length;
  1947. // add callback to jsonp global
  1948. var self = this;
  1949. callbacks.push(function (msg) {
  1950. self.onData(msg);
  1951. });
  1952. // append t…

Large files files are truncated, but you can click here to view the full file