UNPKG

echo.io

Version:

A socket.io server implementation for laravel-echo

197 lines (155 loc) 6.45 kB
"use strict"; var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } var Adapter = function () { function Adapter() { _classCallCheck(this, Adapter); this.presences = new Map(); this.connections = new Map(); } /** * Handle new presence subscription. * * @param userId * @param channel * @param socket * @param status * * @return {void} */ _createClass(Adapter, [{ key: "subscribePresence", value: function subscribePresence(userId, channel, socket, status) { var _this = this; socket.join(channel, function () { // presence index var index = userId + "-" + channel; if (!_this.presences.has(index)) { _this.presences.set(index, { userId: userId, status: status, channel: channel, connections: 0 }); _this.io.dispatchJoining(channel, socket, status); } // we need to keep track of the presence's // multiple sockets connections. if (!_this.connections.has(socket.id)) { _this.connections.set(socket.id, [index]); } else { _this.connections.get(socket.id).push(index); } _this.presences.get(index).connections += 1; _this.io.dispatchSubscribed(channel, socket.id, _this.channelStatuses(channel, userId)); }); } /** * Handle presence unsubscribe. * * @param socket * @param channel */ }, { key: "unsubscribePresence", value: function unsubscribePresence(socket, channel) { var _this2 = this; // get presence index var index = this.connections.get(socket.id).find(function (i) { return i.includes(channel); }); // get all sockets related to the presence index. var socketsIds = this.getPresenceSocketsIds(index); // all related sockets should be processed first socketsIds.forEach(function (id) { // remove any socket/presence relation reference. var position = _this2.connections.get(id).indexOf(index); if (position > -1) { _this2.connections.get(id).splice(position, 1); } // purge connections map if (!_this2.connections.get(id).length) { _this2.connections.delete(id); } // destroy socket/channel binding var socket = _this2.io.sockets.connected[id]; if (socket) socket.leave(channel); }); this.io.dispatchLeaving(channel, null, this.presences.get(index).status); this.presences.delete(index); } /** * Handle socket disconnect event. * * @param socket * @param reason */ }, { key: "ondisconnecting", value: function ondisconnecting(socket) { var _this3 = this; var indexes = void 0; if (indexes = this.connections.get(socket.id)) { // all related presences should be processed first indexes.forEach(function (index) { var presence = _this3.presences.get(index); presence.connections -= 1; if (presence.connections <= 0) { _this3.unsubscribePresence(socket, presence.channel); } }); this.connections.delete(socket.id); } } /** * Get channel presences statuses. * * @param userId * @param channel * * @return {Array} */ }, { key: "channelStatuses", value: function channelStatuses(channel, userId) { var statuses = []; var _iteratorNormalCompletion = true; var _didIteratorError = false; var _iteratorError = undefined; try { for (var _iterator = this.presences.keys()[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) { var key = _step.value; if (key.includes(channel) && key.indexOf(userId) !== 0) { statuses.push(this.presences.get(key).status); } } } catch (err) { _didIteratorError = true; _iteratorError = err; } finally { try { if (!_iteratorNormalCompletion && _iterator.return) { _iterator.return(); } } finally { if (_didIteratorError) { throw _iteratorError; } } } return statuses; } /** * Get all sockets connections for a given presence. * * @param pIndex * * @return {Array} */ }, { key: "getPresenceSocketsIds", value: function getPresenceSocketsIds(pIndex) { var _this4 = this; return Array.from(this.connections.keys).filter(function (socketId) { return _this4.connections.get(socketId).includes(pIndex); }); } }]); return Adapter; }(); module.exports = Adapter;