0

I need to break a timer on a socket event and my Nodejs Express Socket.io App looks like this:

app.js

const express = require('express') ;
const app = express();
const server = require('http').Server(app);
const io = require('socket.io')(server);
const api = require('./routes/api');

const users = io.of('/users') ;

const usersNamespace= (socket) => {
   socket.on('disconnect',()=>{
   });
}

users.on('connection',usersNamespace) ;

app.use('/api', api);
// make socket.io accessible in the express router
app.use((req,res,next)=>{
   req.io = io;
   req.users = users;
   next();
});
server.listen('8000');

my ./routes/api.js file looks like:

var express = require('express');
var router = express.Router();

router.post('/test',req,res) {
    // broadcast body of request to users namespace
    req.users.emit('restreq',req.body) ;

    var timer = setInterval(()=>{
       console.log('hello');
    }, 5000);

    res.status(200).json('received') ;
}

module.exports = router;

The question is how i can do clearInterval and stop the timer on a receiving socket event?

Vahid Alimohamadi
  • 4,900
  • 2
  • 22
  • 37

1 Answers1

0

You can pass a function or object to deal with intervals as you do with users:

app.js

const express = require('express') ;
const app = express();
const server = require('http').Server(app);
const io = require('socket.io')(server);
const api = require('./routes/api');

const users = io.of('/drivers') ;

const timer = {
    hInterval: null,
    register: hInterval => {
        timer.hInterval = hInterval
    },
    disable: () => {
        clearInterval(timer.hInterval)
        timer.hInterval = null
    }
}

const usersNamespace = socket => {
   socket.on('disconnect', () => {
       timer.disable()
   });
}

users.on('connection', usersNamespace) ;

app.use('/api', api);
// make socket.io accessible in the express router
app.use((req, res, next)=>{
   req.io = io;
   req.users = users;
   req.timer = timer;
   next();
});
server.listen('8000');

api.js:

var express = require('express');
var router = express.Router();

router.post('/test', req,res) {
    // broadcast body of request to users namespace
    req.users.emit('restreq',req.body) ;
    req.timer.register(setInterval(() => {
       console.log('hello');
    }, 5000));

    res.status(200).json('received') ;
}

module.exports = router;
Miguel Calderón
  • 3,001
  • 1
  • 16
  • 18
  • The timer does not stop on `req.timer.disable()` or `timer.disable()` on socket event. Why? – Vahid Alimohamadi Feb 27 '18 at 22:54
  • My bad, there was a typo, sorry. Try again with updated code, please. – Miguel Calderón Feb 28 '18 at 08:03
  • I did correct the typo too, But according to [this](https://stackoverflow.com/questions/11300654/storing-the-return-value-of-node-js-settimeout-in-redis) , the point is i should save the timer id and do `clearInterval` on it. – Vahid Alimohamadi Feb 28 '18 at 08:36
  • That was already being done. I've changed a conflicting variable name just in case, can you test the code again, please? – Miguel Calderón Feb 28 '18 at 08:57
  • I did test it. The point is `setInterval` and `setTimeout` will return a circular object which contains identification and details of each instance of timer. We need to address correct instance when we need to break a specific timer on socket event. So i use the `setInterval` like this: `global.timers[index] = setInterval(function(),1000)` then save the index as a `redis` key, Then i can access a specific timer with combination use of redis and array of timers. Thanks for your attention. – Vahid Alimohamadi Feb 28 '18 at 21:13
  • That seems like a good approach - I didn't account for concurrence because I didn't know it was needed, sorry. – Miguel Calderón Mar 01 '18 at 09:17