2013-12-09 31 views
7

我想分享socket.io的Socket对象在不同的​​node.js模块,虽然我失败了,并得到空物体共享socket.io到其他模块提供了空对象

Cannot call method 'on' of undefined 

我的代码:

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; 

路由/ rss.js

io = require(__dirname + '/../app'); 

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

这是输出从我这得到:

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

虽然我已经试过,我可以做同样的socket.io只有一个(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'}); 
}); 

回答

15

由于在app.js中,您有:

exports.io = io; 

那么你就需要使用它,像这样:

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

这是你说的,你连接一个名为io到模块,所以当你需要这个模块,你会得到一个具有io对象属性财产集。

你也可以做

module.exports = io; 

,然后离开rss.js因为你现在拥有它。


所有这一切说,如果你与节点运行app.js,你会看到更为常见,看注入到其他模块(而不是周围的其他方式)的io对象;例如:

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 
    }); 
} 
+0

使用这种方法我有时会得到'类型错误:无法调用“发出” undefined'的同时试图使用socketio对象作为全球性的:'var socketio; module.exports = function(io){io.socket。on('connection',function(socket){socketio = socket;});'然后在代码中的某处使用它; – Patryk

+0

设置一个名为'socketio'的顶级变量,它指向最近连接到应用程序的人。如果没有人连接,它将是'未定义的'。 –

3

我通过io对象插入到connection处理程序。

var socket = require('./routes/socket.js'); 

io.sockets.on('connection', function(sock){ 
    socket.stuff(sock, io); 
}); 

./routes/socket.js应包含以下内容:

var socket = module.exports = {}; 

socket.stuff = function(sock, io){ 
    //handle all events here 
}; 
+0

你能多解释一下吗? 'exporting file','socket.js'应该是什么? – Patryk

+0

更新答案 – chovy