UNPKG

loopback-socket

Version:

Loopback module for create Socket.io connections and allow call methods and make subscriptions

134 lines (117 loc) 3.2 kB
'use strict'; const socketioAuth = require('socketio-auth'); const sockets = {}; function invalidMethod(socket, args) { throw new Error('invalid method'); } function getMethod (method) { if (typeof method === 'function') { return method; } if (method && method.model && typeof method.model[method.method] === 'function') { return method.model[method.method]; } return invalidMethod; } function promisify (handler, ...args) { return Promise.resolve() .then(() => { if (handler.length<=args.length) { return handler.apply(null, args); } return new Promise((resolve, reject) => { handler.apply(null, [].concat(args).concat([(err, result) => { if (err) { reject(err); } else { resolve(result); } }])); }); }) } function buildHandler(socket, credentials, handler) { return (args, done) => { return Promise.resolve() .then(() => { return promisify(handler, socket, credentials, args); }) .then((result) => { return { result }; }) .catch((error) => { return { error }; }) .then((data) => { if (done) { done(data); } }); }; } function LoopbackSocket (name, timeout) { this._name = name; this._timeout = timeout || 3000; this._methods = {}; this._connected = []; this._sockets = []; this._io = null; this._auth = (socket, credentials) => {}; } LoopbackSocket.get = function (name, timeout) { if (!sockets[name]) { sockets[name] = new LoopbackSocket(name, timeout); } return sockets[name]; }; LoopbackSocket.prototype.auth = function (auth) { this._auth = auth; }; LoopbackSocket.prototype.defineMethod = function (methodName, method) { this._methods[methodName] = method; }; LoopbackSocket.prototype.removeMethod = function (methodName) { delete this._methods[methodName]; }; LoopbackSocket.prototype.onConnected = function (method) { this._connected.push(method) }; LoopbackSocket.prototype.removeOnConnected = function (method) { const idx = this._connected.indexOf(getMethod(method)); if (idx===-1) return; this._connected.splice(idx, 1); }; LoopbackSocket.prototype.start = function (io) { // Permite autenticar a los usuarios que se conectan this._io = io; socketioAuth(io, { authenticate: (socket, credentials, cb) => { promisify(getMethod(this._auth), socket, credentials) .then((user) => { return Promise.resolve() .then(() => { return this._connected; }) .then((methods) => { return methods.reduce((p, method) => { return p.then(() => { return promisify(getMethod(method), socket, credentials); }); }, Promise.resolve()); }) .then(() => { Object.keys(this._methods) .map((methodName) => { socket.on(methodName, buildHandler(socket, credentials, getMethod(this._methods[methodName]))); }); }) .then(() => { cb(null, true); }) }) .catch(cb); }, timeout: this._timeout }); }; module.exports = LoopbackSocket;