javascript - 访问 Express 路由时加入 socket.IO 房间

标签 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 });
    });
});

如评论所说,路由访问时我想加入一个socket IO房间。

我试过 io.sockets.join 但它们都出现了,因为它们不是函数。全局 IO 范围肯定会通过,因为我可以在控制台日志中看到它。

使用 EventEmitter 是否更容易做到这一点,并且只需在 socket.js 文件中接收加入房间的事件?如果是这样,有什么想法吗?

非常感谢您的帮助。

最佳答案

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

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

在上面。

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

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


注意:您使用:

var io = global.socketIO;

在 projects.js 的开头作为模块变量有点反模式。这会创建一个模块加载时间依赖项,其中对 global.socketIO 的分配必须在 projects.js 模块加载之前完成,否则您的代码将无法运行。由于模块计时,特别是循环依赖可能是一个复杂的问题,因此这不是创建或拥有的理想情况。

代码中的细微变化,要么根本不使用全局变量(通过显式将 socketIO 值传递给 projects.js 构造函数),要么只是移动 var io = global.socketIO ; 进入每条需要它作为局部变量的路由将完全消除这种加载时间依赖性。

关于javascript - 访问 Express 路由时加入 socket.IO 房间,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37148734/

相关文章:

javascript - 通量存储的动态初始化

node.js - Tedious 或 Sequelize 对 `findOne()` 使用了错误的语法

mysql - NodeJS 数据库(mysql)连接与事务管理

node.js - 在通用应用程序中渲染reactjs组件之前如何获取localStorage?

javascript - 无法在首次单击时禁用链接并在动画完成时重新启用

javascript - 如何将面板锚定到 DOM 元素?

javascript - 如何访问 *ngFor 中定义的变量?

node.js - 如何在具有 yarn 工作空间的 monorepo 中从 nodejs 项目构建 docker 镜像

javascript - 使用来自客户端的信息进行 Node Js/Express api 调用

javascript - SyntaxError : JSON. 解析:React 应用程序上 JSON 数据的第 1 行第 1 列出现意外字符