174 lines
5.1 KiB
JavaScript
174 lines
5.1 KiB
JavaScript
|
(function() {
|
||
|
var Connector, PROTOCOL_6, PROTOCOL_7, Parser, Version, ref;
|
||
|
|
||
|
ref = require('./protocol'), Parser = ref.Parser, PROTOCOL_6 = ref.PROTOCOL_6, PROTOCOL_7 = ref.PROTOCOL_7;
|
||
|
|
||
|
Version = process.env.npm_package_version;
|
||
|
|
||
|
exports.Connector = Connector = (function() {
|
||
|
function Connector(options, WebSocket, Timer, handlers) {
|
||
|
var path;
|
||
|
this.options = options;
|
||
|
this.WebSocket = WebSocket;
|
||
|
this.Timer = Timer;
|
||
|
this.handlers = handlers;
|
||
|
path = this.options.path ? "" + this.options.path : "livereload";
|
||
|
this._uri = "ws" + (this.options.https ? "s" : "") + "://" + this.options.host + ":" + this.options.port + "/" + path;
|
||
|
this._nextDelay = this.options.mindelay;
|
||
|
this._connectionDesired = false;
|
||
|
this.protocol = 0;
|
||
|
this.protocolParser = new Parser({
|
||
|
connected: (function(_this) {
|
||
|
return function(protocol) {
|
||
|
_this.protocol = protocol;
|
||
|
_this._handshakeTimeout.stop();
|
||
|
_this._nextDelay = _this.options.mindelay;
|
||
|
_this._disconnectionReason = 'broken';
|
||
|
return _this.handlers.connected(_this.protocol);
|
||
|
};
|
||
|
})(this),
|
||
|
error: (function(_this) {
|
||
|
return function(e) {
|
||
|
_this.handlers.error(e);
|
||
|
return _this._closeOnError();
|
||
|
};
|
||
|
})(this),
|
||
|
message: (function(_this) {
|
||
|
return function(message) {
|
||
|
return _this.handlers.message(message);
|
||
|
};
|
||
|
})(this)
|
||
|
});
|
||
|
this._handshakeTimeout = new this.Timer((function(_this) {
|
||
|
return function() {
|
||
|
if (!_this._isSocketConnected()) {
|
||
|
return;
|
||
|
}
|
||
|
_this._disconnectionReason = 'handshake-timeout';
|
||
|
return _this.socket.close();
|
||
|
};
|
||
|
})(this));
|
||
|
this._reconnectTimer = new this.Timer((function(_this) {
|
||
|
return function() {
|
||
|
if (!_this._connectionDesired) {
|
||
|
return;
|
||
|
}
|
||
|
return _this.connect();
|
||
|
};
|
||
|
})(this));
|
||
|
this.connect();
|
||
|
}
|
||
|
|
||
|
Connector.prototype._isSocketConnected = function() {
|
||
|
return this.socket && this.socket.readyState === this.WebSocket.OPEN;
|
||
|
};
|
||
|
|
||
|
Connector.prototype.connect = function() {
|
||
|
this._connectionDesired = true;
|
||
|
if (this._isSocketConnected()) {
|
||
|
return;
|
||
|
}
|
||
|
this._reconnectTimer.stop();
|
||
|
this._disconnectionReason = 'cannot-connect';
|
||
|
this.protocolParser.reset();
|
||
|
this.handlers.connecting();
|
||
|
this.socket = new this.WebSocket(this._uri);
|
||
|
this.socket.onopen = (function(_this) {
|
||
|
return function(e) {
|
||
|
return _this._onopen(e);
|
||
|
};
|
||
|
})(this);
|
||
|
this.socket.onclose = (function(_this) {
|
||
|
return function(e) {
|
||
|
return _this._onclose(e);
|
||
|
};
|
||
|
})(this);
|
||
|
this.socket.onmessage = (function(_this) {
|
||
|
return function(e) {
|
||
|
return _this._onmessage(e);
|
||
|
};
|
||
|
})(this);
|
||
|
return this.socket.onerror = (function(_this) {
|
||
|
return function(e) {
|
||
|
return _this._onerror(e);
|
||
|
};
|
||
|
})(this);
|
||
|
};
|
||
|
|
||
|
Connector.prototype.disconnect = function() {
|
||
|
this._connectionDesired = false;
|
||
|
this._reconnectTimer.stop();
|
||
|
if (!this._isSocketConnected()) {
|
||
|
return;
|
||
|
}
|
||
|
this._disconnectionReason = 'manual';
|
||
|
return this.socket.close();
|
||
|
};
|
||
|
|
||
|
Connector.prototype._scheduleReconnection = function() {
|
||
|
if (!this._connectionDesired) {
|
||
|
return;
|
||
|
}
|
||
|
if (!this._reconnectTimer.running) {
|
||
|
this._reconnectTimer.start(this._nextDelay);
|
||
|
return this._nextDelay = Math.min(this.options.maxdelay, this._nextDelay * 2);
|
||
|
}
|
||
|
};
|
||
|
|
||
|
Connector.prototype.sendCommand = function(command) {
|
||
|
if (this.protocol == null) {
|
||
|
return;
|
||
|
}
|
||
|
return this._sendCommand(command);
|
||
|
};
|
||
|
|
||
|
Connector.prototype._sendCommand = function(command) {
|
||
|
return this.socket.send(JSON.stringify(command));
|
||
|
};
|
||
|
|
||
|
Connector.prototype._closeOnError = function() {
|
||
|
this._handshakeTimeout.stop();
|
||
|
this._disconnectionReason = 'error';
|
||
|
return this.socket.close();
|
||
|
};
|
||
|
|
||
|
Connector.prototype._onopen = function(e) {
|
||
|
var hello;
|
||
|
this.handlers.socketConnected();
|
||
|
this._disconnectionReason = 'handshake-failed';
|
||
|
hello = {
|
||
|
command: 'hello',
|
||
|
protocols: [PROTOCOL_6, PROTOCOL_7]
|
||
|
};
|
||
|
hello.ver = Version;
|
||
|
if (this.options.ext) {
|
||
|
hello.ext = this.options.ext;
|
||
|
}
|
||
|
if (this.options.extver) {
|
||
|
hello.extver = this.options.extver;
|
||
|
}
|
||
|
if (this.options.snipver) {
|
||
|
hello.snipver = this.options.snipver;
|
||
|
}
|
||
|
this._sendCommand(hello);
|
||
|
return this._handshakeTimeout.start(this.options.handshake_timeout);
|
||
|
};
|
||
|
|
||
|
Connector.prototype._onclose = function(e) {
|
||
|
this.protocol = 0;
|
||
|
this.handlers.disconnected(this._disconnectionReason, this._nextDelay);
|
||
|
return this._scheduleReconnection();
|
||
|
};
|
||
|
|
||
|
Connector.prototype._onerror = function(e) {};
|
||
|
|
||
|
Connector.prototype._onmessage = function(e) {
|
||
|
return this.protocolParser.process(e.data);
|
||
|
};
|
||
|
|
||
|
return Connector;
|
||
|
|
||
|
})();
|
||
|
|
||
|
}).call(this);
|