'use strict'; var EngineIOClient = require('engine.io-client'); var DubAPIRequestError = require('./errors/requestError.js'); var utils = require('./utils.js'); var endpoints = require('./data/endpoints.js'); function SocketHandler(dubAPI) { this._ = {}; this._.dubAPI = dubAPI; this._.socket = undefined; this._.channels = {}; this._.reconnect = true; this.connectBind = utils.bind(this.connect, this); this.onOpenBind = utils.bind(this.onOpen, this); this.onMessageBind = utils.bind(this.onMessage, this); this.onErrorBind = utils.bind(this.onError, this); this.onCloseBind = utils.bind(this.onClose, this); } SocketHandler.prototype.connect = function() { if (this._.socket) return; this._.reconnect = true; var that = this; this._.dubAPI._.reqHandler.queue({method: 'GET', url: endpoints.authToken}, function(code, body) { if (code !== 200) { that._.dubAPI.emit('error', new DubAPIRequestError(code, that._.dubAPI._.reqHandler.endpoint(endpoints.authToken))); setTimeout(that.connectBind, 5000); return; } that._.socket = new EngineIOClient({ hostname: 'ws.queup.net', secure: true, path: '/ws', query: {access_token: body.data.token}, //eslint-disable-line camelcase transports: ['websocket'] }); that._.socket.on('open', that.onOpenBind); that._.socket.on('message', that.onMessageBind); that._.socket.on('error', that.onErrorBind); that._.socket.on('close', that.onCloseBind); }); }; SocketHandler.prototype.onOpen = function() { var channels = Object.keys(this._.channels); for (var i = 0; i < channels.length; i++) { this._.socket.send(JSON.stringify({action: 10, channel: channels[i]})); if (/^room:/.test(channels[i])) { this._.socket.send(JSON.stringify({action: 14, channel: channels[i], presence: {action: 0, data: {}}})); } } this._.dubAPI.emit('socket:open'); }; SocketHandler.prototype.onMessage = function(data) { try { data = JSON.parse(data); } catch (err) { this._.dubAPI.emit('error', err); return; } this._.dubAPI.emit('socket:message', data); if (data.action === 15 && this._.channels[data.channel]) { try { data.message.data = JSON.parse(data.message.data); } catch (err) { this._.dubAPI.emit('error', err); return; } this._.channels[data.channel](data.message.data); } }; SocketHandler.prototype.onError = function(err) { this._.dubAPI.emit('error', err); }; SocketHandler.prototype.onClose = function() { this._.socket = undefined; if (this._.reconnect) setTimeout(this.connectBind, 5000); this._.dubAPI.emit('socket:close'); }; SocketHandler.prototype.attachChannel = function(channel, callback) { if (this._.socket && !this._.channels[channel]) { this._.socket.send(JSON.stringify({action: 10, channel: channel})); if (/^room:/.test(channel)) { this._.socket.send(JSON.stringify({action: 14, channel: channel, presence: {action: 0, data: {}}})); } } this._.channels[channel] = callback; }; SocketHandler.prototype.detachChannel = function(channel) { if (this._.socket && this._.channels[channel]) this._.socket.send(JSON.stringify({action: 12, channel: channel})); delete this._.channels[channel]; }; SocketHandler.prototype.disconnect = function() { if (!this._.socket) return; this._.reconnect = false; this._.socket.close(); }; module.exports = SocketHandler;