websocket.js 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197
  1. /**
  2. * socket.io
  3. * Copyright(c) 2011 LearnBoost <dev@learnboost.com>
  4. * MIT Licensed
  5. */
  6. (function (exports, io, global) {
  7. /**
  8. * Expose constructor.
  9. */
  10. exports.websocket = WS;
  11. /**
  12. * The WebSocket transport uses the HTML5 WebSocket API to establish an
  13. * persistent connection with the Socket.IO server. This transport will also
  14. * be inherited by the FlashSocket fallback as it provides a API compatible
  15. * polyfill for the WebSockets.
  16. *
  17. * @constructor
  18. * @extends {io.Transport}
  19. * @api public
  20. */
  21. function WS (socket) {
  22. io.Transport.apply(this, arguments);
  23. };
  24. /**
  25. * Inherits from Transport.
  26. */
  27. io.util.inherit(WS, io.Transport);
  28. /**
  29. * Transport name
  30. *
  31. * @api public
  32. */
  33. WS.prototype.name = 'websocket';
  34. /**
  35. * Initializes a new `WebSocket` connection with the Socket.IO server. We attach
  36. * all the appropriate listeners to handle the responses from the server.
  37. *
  38. * @returns {Transport}
  39. * @api public
  40. */
  41. WS.prototype.open = function () {
  42. var query = io.util.query(this.socket.options.query)
  43. , self = this
  44. , Socket
  45. // if node
  46. Socket = require('ws');
  47. // end node
  48. if (!Socket) {
  49. Socket = global.MozWebSocket || global.WebSocket;
  50. }
  51. this.websocket = new Socket(this.prepareUrl() + query);
  52. this.websocket.onopen = function () {
  53. self.onOpen();
  54. self.socket.setBuffer(false);
  55. };
  56. this.websocket.onmessage = function (ev) {
  57. self.onData(ev.data);
  58. };
  59. this.websocket.onclose = function () {
  60. self.onClose();
  61. self.socket.setBuffer(true);
  62. };
  63. this.websocket.onerror = function (e) {
  64. self.onError(e);
  65. };
  66. return this;
  67. };
  68. /**
  69. * Send a message to the Socket.IO server. The message will automatically be
  70. * encoded in the correct message format.
  71. *
  72. * @returns {Transport}
  73. * @api public
  74. */
  75. // Do to a bug in the current IDevices browser, we need to wrap the send in a
  76. // setTimeout, when they resume from sleeping the browser will crash if
  77. // we don't allow the browser time to detect the socket has been closed
  78. if (io.util.ua.iDevice) {
  79. WS.prototype.send = function (data) {
  80. var self = this;
  81. setTimeout(function() {
  82. self.websocket.send(data);
  83. },0);
  84. return this;
  85. };
  86. } else {
  87. WS.prototype.send = function (data) {
  88. this.websocket.send(data);
  89. return this;
  90. };
  91. }
  92. /**
  93. * Payload
  94. *
  95. * @api private
  96. */
  97. WS.prototype.payload = function (arr) {
  98. for (var i = 0, l = arr.length; i < l; i++) {
  99. this.packet(arr[i]);
  100. }
  101. return this;
  102. };
  103. /**
  104. * Disconnect the established `WebSocket` connection.
  105. *
  106. * @returns {Transport}
  107. * @api public
  108. */
  109. WS.prototype.close = function () {
  110. if (this.websocket) this.websocket.close();
  111. return this;
  112. };
  113. /**
  114. * Handle the errors that `WebSocket` might be giving when we
  115. * are attempting to connect or send messages.
  116. *
  117. * @param {Error} e The error.
  118. * @api private
  119. */
  120. WS.prototype.onError = function (e) {
  121. this.socket.onError(e);
  122. };
  123. /**
  124. * Returns the appropriate scheme for the URI generation.
  125. *
  126. * @api private
  127. */
  128. WS.prototype.scheme = function () {
  129. return this.socket.options.secure ? 'wss' : 'ws';
  130. };
  131. /**
  132. * Checks if the browser has support for native `WebSockets` and that
  133. * it's not the polyfill created for the FlashSocket transport.
  134. *
  135. * @return {Boolean}
  136. * @api public
  137. */
  138. WS.check = function () {
  139. // if node
  140. return true;
  141. // end node
  142. return ('WebSocket' in global && !('__addTask' in WebSocket))
  143. || 'MozWebSocket' in global;
  144. };
  145. /**
  146. * Check if the `WebSocket` transport support cross domain communications.
  147. *
  148. * @returns {Boolean}
  149. * @api public
  150. */
  151. WS.xdomainCheck = function () {
  152. return true;
  153. };
  154. /**
  155. * Add the transport to your public io.transports array.
  156. *
  157. * @api private
  158. */
  159. io.transports.push('websocket');
  160. })(
  161. 'undefined' != typeof io ? io.Transport : module.exports
  162. , 'undefined' != typeof io ? io : module.parent.exports
  163. , this
  164. );