echo.io
Version:
A socket.io server implementation for laravel-echo
197 lines (155 loc) • 6.45 kB
JavaScript
;
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;