Sharing socket.io for other modules gives an empty object

I am trying to pass a socket.io socket socket.io to different node.js modules, although I fail and get an empty object with

 Cannot call method 'on' of undefined 

My code is:

app.js

 var express = require('express') , app = express(); var server = require('http').createServer(app) , io = require('socket.io').listen(server) var routes = require('./routes') , path = require('path') , rss = require('./routes/rss') // ... exports.io = io; 

<strong> routes /rss.js

 io = require(__dirname + '/../app'); console.log(io); io.sockets.on('connection', function( console.log("Connection on socket.io on socket"); // .. do stuff }); 

What I get from this:

 $ node app.js info - socket.io started {} /home/XXX/programming/nodejs/node-express-aws/routes/rss.js:10 io.sockets.on('connection', function(socket){ ^ TypeError: Cannot call method 'on' of undefined at Object.<anonymous> (/home/XXX/programming/nodejs/node-express-aws/routes/rss.js:10:12) at Module._compile (module.js:456:26) at Object.Module._extensions..js (module.js:474:10) at Module.load (module.js:356:32) at Function.Module._load (module.js:312:12) at Module.require (module.js:364:17) at require (module.js:380:17) at Object.<anonymous> (/home/XXX/programming/nodejs/node-express-aws/app.js:9:10) at Module._compile (module.js:456:26) at Object.Module._extensions..js (module.js:474:10) 

Although I tried, and I can do the same with socket.io only one file (app.js)

 var express = require('express') , app = express(); var server = require('http').createServer(app) , io = require('socket.io').listen(server) var routes = require('./routes') , path = require('path') , rss = require('./routes/rss') // ... io.sockets.on('connection', function(socket){ logger.debug("Connection on socket.io on socket"); socket.emit('news', {will: 'be recived'}); }); 
+7
javascript module sockets
source share
2 answers

Since in app.js you have:

 exports.io = io; 

then you will need to use it like this:

 var app = require('../app'); var io = app.io; 

That is, you said that you connected a property called io to the module, so when you need this module, you get an object that has the io property.

You can also do

 module.exports = io; 

and then leave rss.js way you have it now.


All that said, if you use app.js with Node, you will often see an io object embedded in other modules (instead of another); eg:

app.js

 var express = require('express') , app = express(); var server = require('http').createServer(app) , io = require('socket.io').listen(server) var routes = require('./routes') , path = require('path') , rss = require('./routes/rss') // ... rss(io); // pass `io` into the `routes` module, // which we define later to be a function // that accepts a Socket.IO object 

routes/rss.js

 module.exports = function(io) { io.sockets.on('connection', function( console.log("Connection on socket.io on socket"); // .. do stuff }); } 
+15
source share

I pass the io object to the connection handler.

 var socket = require('./routes/socket.js'); io.sockets.on('connection', function(sock){ socket.stuff(sock, io); }); 

./routes/socket.js should contain the following:

 var socket = module.exports = {}; socket.stuff = function(sock, io){ //handle all events here }; 
+3
source share

All Articles