访问Express路线时加入socket.IO会议室

时间:2016-05-10 20:50:48

标签: javascript node.js express socket.io

在我的Express应用程序中访问某个路径时,无法加入socket.IO会议室。

所以我目前有以下设置:

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

插座/ 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 });
    });
});

在评论中,我想在访问路由时加入套接字IO室。

我已经尝试了io.sockets.join,但他们都出现了,因为他们不是功能。我可以看到全局IO范围,因为我可以看到控制台日志。

使用EventEmitters更容易这样做,只是接收事件加入 socket.js 文件中的房间?如果是这样,任何想法怎么做?

非常感谢任何帮助。

1 个答案:

答案 0 :(得分:0)

您在特定的socket.io套接字上调用socket.join()。您不能致电io.join()io.sockets.join()。因此,您需要获取要放入房间的特定socket对象,然后调用:

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

就可以了。

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

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

注意:您的使用:

var io = global.socketIO;
在project.js开头作为模块变量的

是一种反模式。这会创建一个模块加载时序依赖关系,其中global.socketIO的赋值必须在加载projects.js模块之前完成,否则您的代码将无效。由于模块时序,特别是循环依赖性可能是一个复杂的问题,因此创建或拥有这种情况并不理想。

您的代码稍微改变为根本不使用全局变量(通过将socketIO值显式传递给projects.js构造函数)或仅将var io = global.socketIO;移动到需要它的每个路径中局部变量将完全消除此加载时序依赖性。