PageRenderTime 44ms CodeModel.GetById 18ms RepoModel.GetById 1ms app.codeStats 0ms

/public/vendor/bower_components/socket.io-client/lib/socket.js

https://github.com/kirillKey/questSearchTrain
JavaScript | 378 lines | 192 code | 65 blank | 121 comment | 24 complexity | cde0a5bab1356814de66a15599def5d2 MD5 | raw file
Possible License(s): Apache-2.0, MIT, 0BSD, GPL-2.0, BSD-3-Clause
  1. /**
  2. * Module dependencies.
  3. */
  4. var parser = require('socket.io-parser');
  5. var Emitter = require('component-emitter');
  6. var toArray = require('to-array');
  7. var on = require('./on');
  8. var bind = require('component-bind');
  9. var debug = require('debug')('socket.io-client:socket');
  10. var hasBin = require('has-binary-data');
  11. var indexOf = require('indexof');
  12. /**
  13. * Module exports.
  14. */
  15. module.exports = exports = Socket;
  16. /**
  17. * Internal events (blacklisted).
  18. * These events can't be emitted by the user.
  19. *
  20. * @api private
  21. */
  22. var events = {
  23. connect: 1,
  24. connect_error: 1,
  25. connect_timeout: 1,
  26. disconnect: 1,
  27. error: 1,
  28. reconnect: 1,
  29. reconnect_attempt: 1,
  30. reconnect_failed: 1,
  31. reconnect_error: 1,
  32. reconnecting: 1
  33. };
  34. /**
  35. * Shortcut to `Emitter#emit`.
  36. */
  37. var emit = Emitter.prototype.emit;
  38. /**
  39. * `Socket` constructor.
  40. *
  41. * @api public
  42. */
  43. function Socket(io, nsp){
  44. this.io = io;
  45. this.nsp = nsp;
  46. this.json = this; // compat
  47. this.ids = 0;
  48. this.acks = {};
  49. this.open();
  50. this.receiveBuffer = [];
  51. this.sendBuffer = [];
  52. this.connected = false;
  53. this.disconnected = true;
  54. this.subEvents();
  55. }
  56. /**
  57. * Mix in `Emitter`.
  58. */
  59. Emitter(Socket.prototype);
  60. /**
  61. * Subscribe to open, close and packet events
  62. *
  63. * @api private
  64. */
  65. Socket.prototype.subEvents = function() {
  66. var io = this.io;
  67. this.subs = [
  68. on(io, 'open', bind(this, 'onopen')),
  69. on(io, 'packet', bind(this, 'onpacket')),
  70. on(io, 'close', bind(this, 'onclose'))
  71. ];
  72. };
  73. /**
  74. * Called upon engine `open`.
  75. *
  76. * @api private
  77. */
  78. Socket.prototype.open =
  79. Socket.prototype.connect = function(){
  80. if (this.connected) return this;
  81. this.io.open(); // ensure open
  82. if ('open' == this.io.readyState) this.onopen();
  83. return this;
  84. };
  85. /**
  86. * Sends a `message` event.
  87. *
  88. * @return {Socket} self
  89. * @api public
  90. */
  91. Socket.prototype.send = function(){
  92. var args = toArray(arguments);
  93. args.unshift('message');
  94. this.emit.apply(this, args);
  95. return this;
  96. };
  97. /**
  98. * Override `emit`.
  99. * If the event is in `events`, it's emitted normally.
  100. *
  101. * @param {String} event name
  102. * @return {Socket} self
  103. * @api public
  104. */
  105. Socket.prototype.emit = function(ev){
  106. if (events.hasOwnProperty(ev)) {
  107. emit.apply(this, arguments);
  108. return this;
  109. }
  110. var args = toArray(arguments);
  111. var parserType = parser.EVENT; // default
  112. if (hasBin(args)) { parserType = parser.BINARY_EVENT; } // binary
  113. var packet = { type: parserType, data: args };
  114. // event ack callback
  115. if ('function' == typeof args[args.length - 1]) {
  116. debug('emitting packet with ack id %d', this.ids);
  117. this.acks[this.ids] = args.pop();
  118. packet.id = this.ids++;
  119. }
  120. if (this.connected) {
  121. this.packet(packet);
  122. } else {
  123. this.sendBuffer.push(packet);
  124. }
  125. return this;
  126. };
  127. /**
  128. * Sends a packet.
  129. *
  130. * @param {Object} packet
  131. * @api private
  132. */
  133. Socket.prototype.packet = function(packet){
  134. packet.nsp = this.nsp;
  135. this.io.packet(packet);
  136. };
  137. /**
  138. * "Opens" the socket.
  139. *
  140. * @api private
  141. */
  142. Socket.prototype.onopen = function(){
  143. debug('transport is open - connecting');
  144. // write connect packet if necessary
  145. if ('/' != this.nsp) {
  146. this.packet({ type: parser.CONNECT });
  147. }
  148. };
  149. /**
  150. * Called upon engine `close`.
  151. *
  152. * @param {String} reason
  153. * @api private
  154. */
  155. Socket.prototype.onclose = function(reason){
  156. debug('close (%s)', reason);
  157. this.connected = false;
  158. this.disconnected = true;
  159. this.emit('disconnect', reason);
  160. };
  161. /**
  162. * Called with socket packet.
  163. *
  164. * @param {Object} packet
  165. * @api private
  166. */
  167. Socket.prototype.onpacket = function(packet){
  168. if (packet.nsp != this.nsp) return;
  169. switch (packet.type) {
  170. case parser.CONNECT:
  171. this.onconnect();
  172. break;
  173. case parser.EVENT:
  174. this.onevent(packet);
  175. break;
  176. case parser.BINARY_EVENT:
  177. this.onevent(packet);
  178. break;
  179. case parser.ACK:
  180. this.onack(packet);
  181. break;
  182. case parser.BINARY_ACK:
  183. this.onack(packet);
  184. break;
  185. case parser.DISCONNECT:
  186. this.ondisconnect();
  187. break;
  188. case parser.ERROR:
  189. this.emit('error', packet.data);
  190. break;
  191. }
  192. };
  193. /**
  194. * Called upon a server event.
  195. *
  196. * @param {Object} packet
  197. * @api private
  198. */
  199. Socket.prototype.onevent = function(packet){
  200. var args = packet.data || [];
  201. debug('emitting event %j', args);
  202. if (null != packet.id) {
  203. debug('attaching ack callback to event');
  204. args.push(this.ack(packet.id));
  205. }
  206. if (this.connected) {
  207. emit.apply(this, args);
  208. } else {
  209. this.receiveBuffer.push(args);
  210. }
  211. };
  212. /**
  213. * Produces an ack callback to emit with an event.
  214. *
  215. * @api private
  216. */
  217. Socket.prototype.ack = function(id){
  218. var self = this;
  219. var sent = false;
  220. return function(){
  221. // prevent double callbacks
  222. if (sent) return;
  223. sent = true;
  224. var args = toArray(arguments);
  225. debug('sending ack %j', args);
  226. var type = hasBin(args) ? parser.BINARY_ACK : parser.ACK;
  227. self.packet({
  228. type: type,
  229. id: id,
  230. data: args
  231. });
  232. };
  233. };
  234. /**
  235. * Called upon a server acknowlegement.
  236. *
  237. * @param {Object} packet
  238. * @api private
  239. */
  240. Socket.prototype.onack = function(packet){
  241. debug('calling ack %s with %j', packet.id, packet.data);
  242. var fn = this.acks[packet.id];
  243. fn.apply(this, packet.data);
  244. delete this.acks[packet.id];
  245. };
  246. /**
  247. * Called upon server connect.
  248. *
  249. * @api private
  250. */
  251. Socket.prototype.onconnect = function(){
  252. this.connected = true;
  253. this.disconnected = false;
  254. this.emit('connect');
  255. this.emitBuffered();
  256. };
  257. /**
  258. * Emit buffered events (received and emitted).
  259. *
  260. * @api private
  261. */
  262. Socket.prototype.emitBuffered = function(){
  263. var i;
  264. for (i = 0; i < this.receiveBuffer.length; i++) {
  265. emit.apply(this, this.receiveBuffer[i]);
  266. }
  267. this.receiveBuffer = [];
  268. for (i = 0; i < this.sendBuffer.length; i++) {
  269. this.packet(this.sendBuffer[i]);
  270. }
  271. this.sendBuffer = [];
  272. };
  273. /**
  274. * Called upon server disconnect.
  275. *
  276. * @api private
  277. */
  278. Socket.prototype.ondisconnect = function(){
  279. debug('server disconnect (%s)', this.nsp);
  280. this.destroy();
  281. this.onclose('io server disconnect');
  282. };
  283. /**
  284. * Called upon forced client/server side disconnections,
  285. * this method ensures the manager stops tracking us and
  286. * that reconnections don't get triggered for this.
  287. *
  288. * @api private.
  289. */
  290. Socket.prototype.destroy = function(){
  291. // clean subscriptions to avoid reconnections
  292. for (var i = 0; i < this.subs.length; i++) {
  293. this.subs[i].destroy();
  294. }
  295. this.io.destroy(this);
  296. };
  297. /**
  298. * Disconnects the socket manually.
  299. *
  300. * @return {Socket} self
  301. * @api public
  302. */
  303. Socket.prototype.close =
  304. Socket.prototype.disconnect = function(){
  305. if (!this.connected) return this;
  306. debug('performing disconnect (%s)', this.nsp);
  307. this.packet({ type: parser.DISCONNECT });
  308. // remove socket from pool
  309. this.destroy();
  310. // fire events
  311. this.onclose('io client disconnect');
  312. return this;
  313. };