在控制器中使用socket.io

我只需要socket.io发送消息给客户端,如果一个新的对象被插入到数据库。 所以我的想法是直接从我的控制器的插入方法发出消息。 在我的server.js文件中,iam创buildsocket.io对象,并尝试使其可用于其他模块:

var server = require('http').createServer(app); var io = require('socket.io').listen(server); //make socket io accessible for other modules module.exports.io = io; 

在我的控制器我尝试使用socket.io这种方式:

 var io = require('../server').io; ... io.sockets.on("connection", function(socket){ passportSocketIo.filterSocketsByUser(io, function (user) { return user.workingAt === socket.handshake.user.workingAt; }).forEach(function(s){ s.send("news", insertedObject); }); }); 

而这里我卡住了。 “连接”事件永远不会被触发,所以消息不会被发射。 这是在单独的文件中使用socket.io的正确方法吗? 不幸的是我找不到复杂的socket.io例子。

你正试图颠倒控制的stream程。 做到这一点的方法是让你的控制器实现一个接口(一个API),你的服务器可以用来传递控制权。

一个简单的例子是:

mycontroller.js

 // no require needed here, at least, I don't think so // Controller agrees to implement the function called "respond" module.exports.respond = function(socket_io){ // this function expects a socket_io connection as argument // now we can do whatever we want: socket_io.on('news',function(newsreel){ // as is proper, protocol logic like // this belongs in a controller: socket.broadcast.emit(newsreel); }); } 

现在在server.js

 var io = require('socket.io').listen(80); var controller = require('./mycontroller'); io.sockets.on('connection', controller.respond ); 

这个例子很简单,因为控制器API看起来像一个socket.iocallback。 但是如果你想传递其他参数给控制器呢? 像io对象本身或代表终点的variables一样? 为此,你需要多一点工作,但并不多。 它基本上是我们经常用来打破或创build闭包的相同技巧:函数生成器:

mycontroller.js

 module.exports.respond = function(endpoint,socket){ // this function now expects an endpoint as argument socket.on('news',function(newsreel){ // as is proper, protocol logic like // this belongs in a controller: endpoint.emit(newsreel); // broadcast news to everyone subscribing // to our endpoint/namespace }); } 

现在在服务器上,我们需要更多的工作来传递结束语:

 var io = require('socket.io').listen(80); var controller = require('./mycontroller'); var chat = io .of('/chat') .on('connection', function (socket) { controller.respond(chat,socket); }); 

请注意,我们直接传递socket ,但我们通过闭包捕获chat 。 有了这个,您可以拥有多个端点,每个端点都有自己的控制器:

 var io = require('socket.io').listen(80); var news_controller = require('./controllers/news'); var chat_controller = require('./controllers/chat'); var news = io .of('/news') .on('connection', function (socket) { news_controller.respond(news,socket); }); var chat = io .of('/chat') .on('connection', function (socket) { chat_controller.respond(chat,socket); }); 

实际上,您甚至可以为每个端点使用多个控制器。 记住,除了订阅事件之外,控制器不做任何事情。 这是正在进行侦听的服务器:

 var io = require('socket.io').listen(80); var news_controller = require('./controllers/news'); var chat_controller = require('./controllers/chat'); var chat = io .of('/chat') .on('connection', function (socket) { news_controller.respond(chat,socket); chat_controller.respond(chat,socket); }); 

它甚至适用于纯socket.io(没有终结点/命名空间):

 var io = require('socket.io').listen(80); var news_controller = require('./controllers/news'); var chat_controller = require('./controllers/chat'); io.sockets.on('connection', function (socket) { news_controller.respond(socket); chat_controller.respond(socket); });