PageRenderTime 42ms CodeModel.GetById 13ms RepoModel.GetById 0ms app.codeStats 0ms

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

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