IceManSpy
IceManSpy

Reputation: 1098

NodeJS, socketIO, multiple files

I'm a little bit confused;

I would like to use socketIO on NodeJS app. I've created this (pseudo)code:

//server.js
var app = express();
//some code...
var router = require('./app/router');
app.use(router);

var server = app.listen(appConfig.app.port, function () {
    var port = server.address().port;
});
var io = require('socket.io')(server);
io.on('connection', function (client) {
    console.log('Client connected...');

    client.on('join', function (data) {
        console.log(data);
    });
});


//client.js
var socket = io.connect('http://localhost:5555');
socket.on('connect', function(data) {
    socket.emit('join', 'Hello World from client');
});

Everything is fine. But !

At now, I would like to emit event in another file. I have router and POST request. I want to emit event on POST request (request handler is in another file).

//router.js
router.route("/addmenu").post(function (req, res) {
        menuModel.addMenu(req.body,function(data){
            //I WANT EMIT HERE
            res.json(data)
        });
    };
);

I have to initialize router before start server, but I have to pass server to IO... How pass IO to router ?

Upvotes: 10

Views: 8616

Answers (3)

morch23mj
morch23mj

Reputation: 89

The answer of @jahnestacado does the job, but in case you already have an existing code base, then you need to change the structure of each file, where you might need the socket.io object, to pass it in as an argument.

A better way to do it then, would be:

To create the getIO() function—just as @jahnestacado did—, where you instantiate the io object (inside server.js), and export it.

var io;
exports.getIO = () => io;

Then require it wherever you need it. But make sure to execute the function only when you need it. Typically inside your controller function:

const getIO = require('../server').getIO;

exports.updateSAE = (req, res) => {
  let io = getIO();
  io.emit();
  // rest of your controller function code
}

Note that I did not call the getIO function outside the controller function. For example, the following would probably not work:

const getIO = require('../server').getIO;
var io = getIO();

exports.updateSAE = (req, res) => {
  io.emit();
  // rest of your controller function code
}

Simply because the socket.io object could have not been initialized when you call the function, thus returning undefined.

Upvotes: 1

jahnestacado
jahnestacado

Reputation: 593

You can try this

//server.js
var app = express();
//some code...
var io;
var getIOInstance = function(){
  return io;
};
var router = require('./app/router')(getIOInstance);
app.use(router);

var server = app.listen(appConfig.app.port, function () {
    var port = server.address().port;
});

io = require('socket.io')(server);
io.on('connection', function (client) {
    console.log('Client connected...');

    client.on('join', function (data) {
        console.log(data);
    });
});

//router.js
module.exports = function(getIOInstance){
    router.route("/addmenu").post(function (req, res) {
        menuModel.addMenu(req.body,function(data){
            //I WANT EMIT HERE
            getIOInstance().sockets.emit(...)
            res.json(data)
        });
    };
    return router;
);

This solution will work if you want to 'notify' all connected clients.

If you need to notify only a specific client, then I will advise you to use an event-emitter module in order to communicate these events and not share your socket instances across multiple files.

Upvotes: 4

ashr
ashr

Reputation: 299

In router.js you can do something like:

//router.js
module.exports = function(io) {
var router = //What you declared it to be
router.route("/addmenu").post(function (req, res) {
    menuModel.addMenu(req.body,function(data){
        //I WANT EMIT HERE
        res.json(data)
    });
};
);
return router;
}


 //server.js
 //Change this line to be like the one below
var router = require('./app/router');
//.........
//.......

//Desired way
var router = require('./app/router')(io);

Upvotes: 2

Related Questions