Michael Frey
Michael Frey

Reputation: 918

Structuring Modules and socket.io in node.js

I seem to lack understanding of how to structure node modules.

I have the following in app.js.

var io = require('socket.io')(http);
io.on('connection', function(socket){

    socket.on('disconnect', function(){
        console.log('user disconnected');
    });

    console.log("New user " + socket.id);
    users.push(socket.id);
    io.sockets.emit("user_count", users.length);
});

And this is fine. I can react to all kinds of messages from the client, but I also have several modules that need to react to different messages. For example my cardgame.js module should react to:

socket.on("joinTable"...
socket.on("playCard"

While my chessgame.js should react to

socket.on("MakeAMove"...

and my user.js file handles:

socket.on('register' ...
socket.on('login' ...

How would I link up/structure my files to handle these different messages, so that my file that reacts to socket requests does not become too huge.

Basically it would be great if I could pass the socket object to these modules. But the issue is that until a connection is established the socket will be undefined.

Also if I pass the whole io variable to my modules, then each of those modules would have the io.on('connection',..) call. Not sure if that is even possible or desired.

Upvotes: 0

Views: 153

Answers (1)

Patrick Evans
Patrick Evans

Reputation: 42736

You don't need to pass the whole io object around (but you can, I do just in case I need it). Just pass the socket to the modules on connection, and then set your specific on callbacks for the module

main

io.on("connection",function(socket){
    //...
    require("../someModule")(socket);
    require("../smoreModule")(socket);
});

socket

//Convenience methods to setup event callback(s) and 
//prepend socket to the argument list of callback
function apply(fn,socket,context){
    return function(){
        Array.prototype.unshift.call(arguments,socket);
        fn.apply(context,arguments);
    };
}

//Pass context if you wish the callback to have the context
//of some object, i.e. use 'this' within the callback
module.exports.setEvents = function(socket,events,context){
    for(var name in events) {
        socket.on(name,apply(events[name],socket,context));
    }
};

someModule

var events = {
    someAction:function(socket,someData){

    },
    smoreAction:function(socket,smoreData){

    }
}

module.exports = function(socket){
   //other initialization code
   //...

   //setup the socket callbacks for the connected user
   require("../socket").setEvents(socket,events);
};

Upvotes: 1

Related Questions