io.js 3.7 KB

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