简体   繁体   中英

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 ?

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.

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);

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM