connector.js 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173
  1. (function() {
  2. var Connector, PROTOCOL_6, PROTOCOL_7, Parser, Version, ref;
  3. ref = require('./protocol'), Parser = ref.Parser, PROTOCOL_6 = ref.PROTOCOL_6, PROTOCOL_7 = ref.PROTOCOL_7;
  4. Version = process.env.npm_package_version;
  5. exports.Connector = Connector = (function() {
  6. function Connector(options, WebSocket, Timer, handlers) {
  7. var path;
  8. this.options = options;
  9. this.WebSocket = WebSocket;
  10. this.Timer = Timer;
  11. this.handlers = handlers;
  12. path = this.options.path ? "" + this.options.path : "livereload";
  13. this._uri = "ws" + (this.options.https ? "s" : "") + "://" + this.options.host + ":" + this.options.port + "/" + path;
  14. this._nextDelay = this.options.mindelay;
  15. this._connectionDesired = false;
  16. this.protocol = 0;
  17. this.protocolParser = new Parser({
  18. connected: (function(_this) {
  19. return function(protocol) {
  20. _this.protocol = protocol;
  21. _this._handshakeTimeout.stop();
  22. _this._nextDelay = _this.options.mindelay;
  23. _this._disconnectionReason = 'broken';
  24. return _this.handlers.connected(_this.protocol);
  25. };
  26. })(this),
  27. error: (function(_this) {
  28. return function(e) {
  29. _this.handlers.error(e);
  30. return _this._closeOnError();
  31. };
  32. })(this),
  33. message: (function(_this) {
  34. return function(message) {
  35. return _this.handlers.message(message);
  36. };
  37. })(this)
  38. });
  39. this._handshakeTimeout = new this.Timer((function(_this) {
  40. return function() {
  41. if (!_this._isSocketConnected()) {
  42. return;
  43. }
  44. _this._disconnectionReason = 'handshake-timeout';
  45. return _this.socket.close();
  46. };
  47. })(this));
  48. this._reconnectTimer = new this.Timer((function(_this) {
  49. return function() {
  50. if (!_this._connectionDesired) {
  51. return;
  52. }
  53. return _this.connect();
  54. };
  55. })(this));
  56. this.connect();
  57. }
  58. Connector.prototype._isSocketConnected = function() {
  59. return this.socket && this.socket.readyState === this.WebSocket.OPEN;
  60. };
  61. Connector.prototype.connect = function() {
  62. this._connectionDesired = true;
  63. if (this._isSocketConnected()) {
  64. return;
  65. }
  66. this._reconnectTimer.stop();
  67. this._disconnectionReason = 'cannot-connect';
  68. this.protocolParser.reset();
  69. this.handlers.connecting();
  70. this.socket = new this.WebSocket(this._uri);
  71. this.socket.onopen = (function(_this) {
  72. return function(e) {
  73. return _this._onopen(e);
  74. };
  75. })(this);
  76. this.socket.onclose = (function(_this) {
  77. return function(e) {
  78. return _this._onclose(e);
  79. };
  80. })(this);
  81. this.socket.onmessage = (function(_this) {
  82. return function(e) {
  83. return _this._onmessage(e);
  84. };
  85. })(this);
  86. return this.socket.onerror = (function(_this) {
  87. return function(e) {
  88. return _this._onerror(e);
  89. };
  90. })(this);
  91. };
  92. Connector.prototype.disconnect = function() {
  93. this._connectionDesired = false;
  94. this._reconnectTimer.stop();
  95. if (!this._isSocketConnected()) {
  96. return;
  97. }
  98. this._disconnectionReason = 'manual';
  99. return this.socket.close();
  100. };
  101. Connector.prototype._scheduleReconnection = function() {
  102. if (!this._connectionDesired) {
  103. return;
  104. }
  105. if (!this._reconnectTimer.running) {
  106. this._reconnectTimer.start(this._nextDelay);
  107. return this._nextDelay = Math.min(this.options.maxdelay, this._nextDelay * 2);
  108. }
  109. };
  110. Connector.prototype.sendCommand = function(command) {
  111. if (this.protocol == null) {
  112. return;
  113. }
  114. return this._sendCommand(command);
  115. };
  116. Connector.prototype._sendCommand = function(command) {
  117. return this.socket.send(JSON.stringify(command));
  118. };
  119. Connector.prototype._closeOnError = function() {
  120. this._handshakeTimeout.stop();
  121. this._disconnectionReason = 'error';
  122. return this.socket.close();
  123. };
  124. Connector.prototype._onopen = function(e) {
  125. var hello;
  126. this.handlers.socketConnected();
  127. this._disconnectionReason = 'handshake-failed';
  128. hello = {
  129. command: 'hello',
  130. protocols: [PROTOCOL_6, PROTOCOL_7]
  131. };
  132. hello.ver = Version;
  133. if (this.options.ext) {
  134. hello.ext = this.options.ext;
  135. }
  136. if (this.options.extver) {
  137. hello.extver = this.options.extver;
  138. }
  139. if (this.options.snipver) {
  140. hello.snipver = this.options.snipver;
  141. }
  142. this._sendCommand(hello);
  143. return this._handshakeTimeout.start(this.options.handshake_timeout);
  144. };
  145. Connector.prototype._onclose = function(e) {
  146. this.protocol = 0;
  147. this.handlers.disconnected(this._disconnectionReason, this._nextDelay);
  148. return this._scheduleReconnection();
  149. };
  150. Connector.prototype._onerror = function(e) {};
  151. Connector.prototype._onmessage = function(e) {
  152. return this.protocolParser.process(e.data);
  153. };
  154. return Connector;
  155. })();
  156. }).call(this);