io.js 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
  1. 'use strict';
  2. // This file contains all the logic for Socket.IO
  3. const app = require('./app');
  4. const actions = require('./actions');
  5. const cache = require('./cache');
  6. const utils = require('./utils');
  7. const db = require('./db');
  8. module.exports = {
  9. io: null,
  10. init: (cb) => {
  11. //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)
  12. this.io = require('socket.io')(app.server);
  13. this.io.use((socket, next) => {
  14. let cookies = socket.request.headers.cookie;
  15. let SID = utils.cookies.parseCookies(cookies).SID;
  16. if (!SID) SID = "NONE";
  17. cache.hget('sessions', SID, (err, session) => {
  18. if (err) SID = null;
  19. socket.session = (session) ? session : {};
  20. socket.session.socketId = socket.id;
  21. return next();
  22. });
  23. });
  24. this.io.on('connection', socket => {
  25. console.info('User has connected');
  26. // catch when the socket has been disconnected
  27. socket.on('disconnect', () => {
  28. // remove the user from their current station (if any)
  29. if (socket.session) {
  30. //actions.stations.leave(socket.sessionId, result => {});
  31. // Remove session from Redis
  32. //cache.hdel('sessions', socket.session.sessionId);
  33. }
  34. console.info('User has disconnected');
  35. });
  36. // catch errors on the socket (internal to socket.io)
  37. socket.on('error', err => console.error(err));
  38. // have the socket listen for each action
  39. Object.keys(actions).forEach((namespace) => {
  40. Object.keys(actions[namespace]).forEach((action) => {
  41. // the full name of the action
  42. let name = `${namespace}.${action}`;
  43. // listen for this action to be called
  44. socket.on(name, function () {
  45. let args = Array.prototype.slice.call(arguments, 0, -1);
  46. let cb = arguments[arguments.length - 1];
  47. // load the session from the cache
  48. cache.hget('sessions', socket.session.sessionId, (err, session) => {
  49. if (err && err !== true) {
  50. if (typeof cb === 'function') return cb({
  51. status: 'error',
  52. message: 'An error occurred while obtaining your session'
  53. });
  54. }
  55. // make sure the sockets sessionId isn't set if there is no session
  56. if (socket.session.sessionId && session === null) delete socket.session.sessionId;
  57. // call the action, passing it the session, and the arguments socket.io passed us
  58. actions[namespace][action].apply(null, [socket.session].concat(args).concat([
  59. (result) => {
  60. // respond to the socket with our message
  61. if (typeof cb === 'function') return cb(result);
  62. }
  63. ]));
  64. });
  65. })
  66. })
  67. });
  68. if (socket.session.sessionId) {
  69. cache.hget('sessions', socket.session.sessionId, (err, session) => {
  70. if (err && err !== true) socket.emit('ready', false);
  71. else if (session && session.userId) {
  72. db.models.user.findOne({ _id: session.userId }, (err, user) => {
  73. if (err || !user) return socket.emit('ready', false);
  74. let role = '';
  75. let username = '';
  76. let userId = '';
  77. if (user) {
  78. role = user.role;
  79. username = user.username;
  80. userId = session.userId;
  81. }
  82. socket.emit('ready', true, role, username, userId);
  83. });
  84. } else socket.emit('ready', false);
  85. })
  86. } else socket.emit('ready', false);
  87. });
  88. cb();
  89. }
  90. };