Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Socket.IO - Middleware and scoping: how should I access global IO object from external middleware?

I've split some parts of a Socket.IO application I'm working on into various middleware that perform operations necessary to the application like managing sessions and enforcing access restrictions.

I am currently trying to write another set of middleware functions to handle a list of currently connected sockets intended to be used to kick specific clients from the server, and I find myself in need of the global io object within the context of a socket.on event callback to broadcast messages to specific rooms via io.sockets.in('room').emit(...).

As far as I know, if you split your socket events out of your main program the way I have there is no tidy way to access the global io object in an external file. Merely require-ing the Socket.IO module within the external file will not be enough.

I have come up with this workaround to inject the global io object and return a function matching the signature Socket.IO expects from middleware and it appears to work. Still, I worry.

Is there a more elegant solution for my problem? A cleaner alternative, maybe? Have I missed something in the documentation?

And are there any hidden gotchas to the "solution" I've found?

index.js

// Other required stuff- Express.js, Mongoose, whatever.
var io = require('socket.io').listen(server);

var Middleware = require('./middleware.js')(io);
io.use(Middleware);

server.listen(port);

middleware.js

module.exports = function(io) {
    return function(socket, next) {
        socket.on('kickUser', function(data) {
            // Do something with the global io object here.
        });
        return next();
    };
};

Any advice would be welcome!

like image 625
Connor Avatar asked Feb 09 '23 11:02

Connor


1 Answers

The io object is an instance a socket.io Server.

This instance is also available via socket.server from within an event handler.

The following two examples are equivalent:

module.exports = function(io) {
    return function(socket, next) {
        socket.on('kickUser', function(data) {
            io.emit('userKicked', socket.id);
        });
        return next();
    };
};

module.exports = function() {
    return function(socket, next) {
        socket.on('kickUser', function(data) {
            socket.server.emit('userKicked', socket.id);
        });
        return next();
    };
};
like image 86
Mark Cola Avatar answered Feb 11 '23 01:02

Mark Cola