var log = console.log;
var chatEvent = new EventEmitter();
var ASocket = (function (log, chatEvent) {
var ws = {
readyState: 100
};
var _this;
function TheSocket(credentials, callback) {
_this = this;
_this.connCredentials = credentials;
this.connect(callback);
}
TheSocket.prototype.connCredentials;
TheSocket.prototype.showDebug = false;
TheSocket.prototype.callbacksToCall = [];
TheSocket.prototype.isConnecting = false;
TheSocket.prototype.isFirstConnection = true;
TheSocket.prototype.isDisconnected = false;
TheSocket.prototype.reconnectPayload;
TheSocket.prototype.executeCallbacks = function (callbacks, param, then) {
if (callbacks.length) {
for (var i = callbacks.length - 1; i >= 0; i--) {
callbacks[i](param);
}
}
if (then) then();
}
TheSocket.prototype.constructTime = function () {
var d = new Date();
return d.getTime();
}
TheSocket.prototype.connect = function (callback) {
//Stop if user disconnected manually(leave room)
if (this.isDisconnected) {
clearInterval(retryInterval);
return;
}
//Let's see if we have connection already
if (ws)
if (ws.readyState == 1) {
if (callback) callback();
return;
} else if (_this.isConnecting) {
if (callback) {
_this.callbacksToCall.push(callback);
}
return;
}
setTimeout(function () {
chatEvent.emit('conn.change', 'connecting');
chatEvent.emit('conn.connecting');
}, 250);
_this.isConnecting = true;
var retryNum = 1;
var retryInterval = setInterval(function () {
//if we are not connected or connecting
if (ws.readyState != 1 && ws.readyState != 0) {
//Log message if its not first
if (!_this.isFirstConnection) {
log('Retrying connection(' + retryNum + ')...');
//Call connection status callbacks
chatEvent.emit('conn.change', 'reconnecting', retryNum);
chatEvent.emit('conn.reconnecting', retryNum);
}
try {
ws = new WebSocket(_this.connCredentials.url);
} catch (e) {
_this.handleError(e);
}
var stateCheckInterval = setInterval(function () {
//Continue checking until our socket is not in 'connecting state'
if (ws.readyState != 0) {
clearInterval(stateCheckInterval);
}
//Init
if (ws.readyState == 1) {
clearInterval(retryInterval);
_this.init();
_this.isConnecting = false;
retryNum = 1;
//If its reconnecting, then we will send TheSocket.prototype.reconnectPayload
if (!_this.isFirstConnection && _this.reconnectPayload) {
_this.send(_this.reconnectPayload);
}
//Execute
if (callback) callback();
_this.executeCallbacks(_this.callbacksToCall, null, function () {
_this.callbacksToCall = [];
});
log("Connection established.");
//Call connection status callbacks
chatEvent.emit('conn.change', 'connected');
chatEvent.emit('conn.connected');
}
}, 100);
retryNum++;
_this.isFirstConnection = false;
}
}, 1500);
}
TheSocket.prototype.getSocket = function () {
return ws;
};
TheSocket.prototype.init = function () {
ws.onmessage = (message) => this.handleMessage(message);
//ws.onopen = () => this.ping();
ws.onclose = () => this.handleClose();
ws.onerror = () => this.handleError();
};
TheSocket.prototype.send = function (data, callback) {
if (ws.readyState == 1) {
ws.send(JSON.stringify(data));
//exec callback
if (callback) callback();
} else {
this.connect(function () {
_this.send(data);
//exec callback
if (callback) callback();
});
}
};
TheSocket.prototype.ping = function () {
this.send({
command: 'system.ping',
time: _this.constructTime()
});
};
TheSocket.prototype.pong = function () {
this.send({
command: 'system.pong',
time: _this.constructTime()
});
};
TheSocket.prototype.handleMessage = function (message) {
if (this.showDebug) {
var dt = new Date();
var now = dt.getHours() + ':' + dt.getMinutes() + ':' + dt.getSeconds();
log(now + ': ' + message.data);
}
var recvMessage = JSON.parse(message.data);
var command = recvMessage.command;
//Emit events bound to this message command
chatEvent.emit(command, recvMessage);
};
TheSocket.prototype.handleError = function (e) {
chatEvent.emit('conn.error', e);
log('Error: ');
log(JSON.stringify(e));
};
TheSocket.prototype.handleClose = function (e) {
if (!_this.isDisconnected) {
chatEvent.emit('conn.closed', e);
}
this.connect();
};
TheSocket.prototype.setReconnectPayload = function (payload) {
_this.reconnectPayload = payload;
};
TheSocket.prototype.disconnect = function () {
//Mark connection as disconnected
_this.isDisconnected = true;
//Disconnect
ws.close();
//Emit event that connection is disconnected
chatEvent.emit('conn.disconnected')
};
//When ping message is received
chatEvent.on('system.ping', function () {
_this.pong();
});
chatEvent.on('system.pong', function () {
log('Pong message received');
});
return TheSocket;
})(log, chatEvent);
|