123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126 |
- 'use strict';
- // This file contains all the logic for Socket.IO
- const app = require('./app');
- const actions = require('./actions');
- const async = require('async');
- const cache = require('./cache');
- const utils = require('./utils');
- const db = require('./db');
- module.exports = {
- io: null,
- init: (cb) => {
- //TODO Check every 30s/60s, for all sockets, if they are still allowed to be in the rooms they are in, and on socket at all (permission changing/banning)
- this.io = require('socket.io')(app.server);
- this.io.use((socket, next) => {
- let cookies = socket.request.headers.cookie;
- let SID = utils.cookies.parseCookies(cookies).SID;
- async.waterfall([
- (next) => {
- if (!SID) return next('No SID.');
- next();
- },
- (next) => {
- cache.hget('sessions', SID, next);
- },
- (session, next) => {
- if (!session) return next('No session found.');
- session.refreshDate = Date.now();
- socket.session = session;
- cache.hset('sessions', SID, session, next);
- }
- ], () => {
- if (!socket.session) {
- socket.session = {socketId: socket.id};
- } else socket.session.socketId = socket.id;
- next();
- });
- });
- this.io.on('connection', socket => {
- console.info('User has connected');
- // catch when the socket has been disconnected
- socket.on('disconnect', () => {
- // remove the user from their current station (if any)
- if (socket.session) {
- //actions.stations.leave(socket.sessionId, result => {});
- // Remove session from Redis
- //cache.hdel('sessions', socket.session.sessionId);
- }
- console.info('User has disconnected');
- });
- // catch errors on the socket (internal to socket.io)
- socket.on('error', err => console.error(err));
- // have the socket listen for each action
- Object.keys(actions).forEach((namespace) => {
- Object.keys(actions[namespace]).forEach((action) => {
- // the full name of the action
- let name = `${namespace}.${action}`;
- // listen for this action to be called
- socket.on(name, function () {
- let args = Array.prototype.slice.call(arguments, 0, -1);
- let cb = arguments[arguments.length - 1];
- // load the session from the cache
- cache.hget('sessions', socket.session.sessionId, (err, session) => {
- if (err && err !== true) {
- if (typeof cb === 'function') return cb({
- status: 'error',
- message: 'An error occurred while obtaining your session'
- });
- }
- // make sure the sockets sessionId isn't set if there is no session
- if (socket.session.sessionId && session === null) delete socket.session.sessionId;
- // call the action, passing it the session, and the arguments socket.io passed us
- actions[namespace][action].apply(null, [socket.session].concat(args).concat([
- (result) => {
- // respond to the socket with our message
- if (typeof cb === 'function') return cb(result);
- }
- ]));
- });
- })
- })
- });
- if (socket.session.sessionId) {
- cache.hget('sessions', socket.session.sessionId, (err, session) => {
- if (err && err !== true) socket.emit('ready', false);
- else if (session && session.userId) {
- db.models.user.findOne({ _id: session.userId }, (err, user) => {
- if (err || !user) return socket.emit('ready', false);
- let role = '';
- let username = '';
- let userId = '';
- if (user) {
- role = user.role;
- username = user.username;
- userId = session.userId;
- }
- socket.emit('ready', true, role, username, userId);
- });
- } else socket.emit('ready', false);
- })
- } else socket.emit('ready', false);
- });
- cb();
- }
- };
|