在访问Express路线时join一个socket.IO房间

在Express应用程序中访问特定路线时遇到了一些问题,

所以我现在有以下设置:

app.js

var express = require('express'); var app = express(); var http = require('http').Server(app); var socketio = require('socket.io').listen(http); var socketjs = require(libs + 'sockets/socket.js'); ... var server = http.listen(app.get('port'), function() { debug('Taskful server listening on port ' + app.get('port')); log.info('Taskful server listening on port ' + app.get('port')); }); global.socketIO = socketio; socketjs.connect(server); 

sockets/ socket.js

 var libs = process.cwd() + '/libs/'; var log = require(libs + 'log')(module); module.exports.connect = function(server) { var io = global.socketIO; io.on('connection', function (socket) { //This comes through log.info('Connection to socket.io'); }); } 

路线 – projects.js

 var io = global.socketIO; ... router.get('/:id', function(req, res) { projectController.findByIdExtended(req, res, function(err, ret) { if (err) { res.redirect('/projects'); } req.session.viewingProject = req.params.id; //I would like to be able to join the room here io.room = 'project_' + req.session.viewingProject; io.join(io.room); var db_project = ret[0]; var db_tasks = ret[1]; res.render('project', { user : req.user, project : db_project, tasks: db_tasks }); }); }); 

正如在注释中,我想join一个套接字IO的房间,当访问路线。

我试过io.sockets.join但他们都是因为他们不是function。 全球IO范围绝对是通过我可以看到它的控制台日志。

使用EventEmitter这样做更容易,只需要接收事件来joinsocket.js文件中的一个房间? 如果是这样,任何想法如何做呢?

非常感谢您的帮助。

您可以在特定的socket.io套接字上调用socket.join() 。 你不要调用io.join()或者io.sockets.join() 。 所以,你需要得到你想要放在一个房间里的特定socket对象,然后调用:

 socket.join('project_' + req.session.viewingProject); 

在上面。

如果您正试图获取与发出当前路由请求的用户关联的特定socket ,则必须在套接字和路由之间build立关联(通常使用已知的cookie标识符)。 您可以从路由中查找该cookie值,然后使用它为当前用户查找正确的socket对象。

看起来你已经在使用一个会话,所以应该已经有一个cookie标识符,你可以使用它将一个路由与一个特定的socket.io连接关联起来。 您可能需要创build一个将io.on('connection')socket.on('disconnect')中的这两个关联的映射对象,以便您可以获取会话ID并在该映射中查找正确的套接字对象。


注意:您使用:

 var io = global.socketIO; 

在projects.js作为一个模块variables的开始是有点反模式。 这将创build一个模块加载时序依赖项,其中必须在projects.js模块加载之前完成对global.socketIO的分配, global.socketIO代码将无法工作。 由于模块时序,特别是循环依赖可能是一个复杂的问题,这不是一个理想的情况下创build或拥有。

你的代码稍微改变,不要全部使用全局variables(通过将socketIO值明确地传递给projects.js构造函数),或者移动var io = global.socketIO; 到每个需要它作为局部variables的路由将完全消除这个加载时间依赖。