0

I broke my app into modules to add to it in the future. I'm using express 4 with the generator and running into issues with adding my multiple socket.io listeners.

In /bin/www

app.io.attach(server);

In app.js

var app = express();

//call socket.io to the app for each route
app.io = require('./socket.io/file1');
app.io = require('./socket.io/file2');
app.io = require('./socket.io/file3');

Everything worked great until I try to add more than one socket.io source file. Then only the last one works. I assume because app.io gets reset each time I call it.

What's the best way to go about this? I want to keep my code broke up as much as possible.

user2650875
  • 165
  • 1
  • 1
  • 6

1 Answers1

1

You're overwriting app.io each time. app.io = require('./socket.io/file1'); isn't "calling socket.io" but assigns app.io to that module. There are multiple ways to solve this, for example:

in app.js:

app.io = [
    require('./socket.io/file1'),
    require('./socket.io/file2'),
    require('./socket.io/file3')
]

in /bin/www:

app.io.forEach(function (socketIo) {
    socketIo.attach(server);
});

This assigns an array to app.io and /bin/www iterates over the array to attach the server to each socket.io instance.

I couldn't test if this works and i suspect it doesn't (I wrote it just to illustrate the first problem in your code). I think one can use only a single socket.io instance per http server. But there is a solution:

tl;dr

Use socket.io namespaces. Create a single instance of socket.io and attach it to the server like you already do, then create "submodules" via io.of("/module-name") in each of your module files (like file1, etc). Please read the documentation to learn more about namespaces.


Update:

There are again multiple options to do that, e.g.: (Warning, code is from one of my own codebases, and is originally written in coffee-script and translated in my head, but you should get the gist)

in io.coffee

var io = require('socket.io')(http)

require('./broadcast.coffee')(io)
require('./livelog.coffee')(io)

Where http is, of course, your http server instance.

in broadcast.coffee

module.exports = function (io) {
    var broadcast = io.of('/broadcast')

    broadcast.on('connection', function (socket) {
        socket.emit('foo', 'bar')
    })
}
Moritz Mahringer
  • 1,240
  • 16
  • 28
  • This completely makes sense. I am already using namespaces in my code. What I want to do is keep my socket.io modules broke up based on my routes. I believe doing the method of what your recommend will allow me to do that. At this point I'm not sure how to get that module to fire off when that route is triggered based on having a single io.js file. – user2650875 Jan 03 '16 at 14:18
  • Worked like a charm! Thanks for the updated example. – user2650875 Jan 04 '16 at 02:16