Socket.io 命名空间和服务器不共享中间件?

Posted

技术标签:

【中文标题】Socket.io 命名空间和服务器不共享中间件?【英文标题】:Socket.io namespaces and server don't share middleware? 【发布时间】:2015-03-09 04:48:56 【问题描述】:

我为我的 socket.io/express 应用程序创建了一些护照身份验证中间件。它看起来像:

io.use(function (socket, next) 
    var data = cookie.parse(socket.handshake.headers.cookie);
    var sessionID = cookieParser.signedCookie(data['connect.sid'], 'my balonga has a first name');
    sessionStore.get(sessionID, function (err, data) 
        if (err) next(err);
        socket.handshake.passport = data.passport;
        next();
    );
);

它工作得很好,但我有一个命名空间,它似乎使用了不同的套接字。这是否意味着我必须为每个命名空间重用我的中间件?

我注意到我连接到我的命名空间,它调用基础服务器的中间件,然后调用命名空间,这意味着如果我在两个地方都包含中间件,我将执行两倍于我需要的操作。我可以在不删除基础层的中间件的情况下防止这种情况吗?这些都不是应用程序破坏者,但它会稍微改变我的架构,我担心我会在某些时候出现身份验证漏洞。

总结:

我必须为每个命名空间重复使用我的中间件吗? 当默认命名空间中间件连接到命名空间时,是否可以在不移除基础层中间件的情况下阻止调用默认命名空间中间件?

【问题讨论】:

如何在 Express 中定义命名空间? 我相信,Express 没有命名空间,它有路由。 Socket.io 有命名空间。 这么想...我使用featherjs来管理套接字之间的共享并表示是否有帮助... 是的,自从我发布了这个,实际上有很多东西可以帮助管理这个,包括我写的一个包 - npmjs.com/package/express-session-socket.io 你使用什么会话中间件? 【参考方案1】:

我必须为每个命名空间重复使用我的中间件吗?

没有。如果您打算按照所写的方式为所有命名空间使用中间件,您可以像现在一样使用io.use()。这会将中间件放在默认的 / 命名空间上。正如您已经注意到的,所有子命名空间上的中间件按顺序触发,从默认开始,在新的 socket.io 连接上。

当默认命名空间中间件连接到命名空间时,是否可以在不移除基础层中间件的情况下阻止调用默认命名空间中间件?

没有。所有命名空间都是默认命名空间的子空间,并且在默认命名空间上定义的任何中间件都会为所有连接触发。如果您只想在某些命名空间上触发您的中间件,您可以避免使用 io.use() 并执行以下操作。

const myMiddleware = function(socket, next) 
    // Do stuff here
;
io.of('/nsp_1').use(myMiddleware);
io.of('/nsp_2').use(myMiddleware);

更模块化的方法

一种更模块化的方法是将不同命名空间的处理程序放在不同的不同文件中,并在这些文件中定义特定于这些命名空间的中间件,同时使用io.use() 作为默认命名空间。

main_app.js

const everthingMiddleware = require('./middleware/everything.js');
io.use(everythingMiddleware);
require('./nsp_1.js')(io.of('/nsp_1'));

nsp_1.js

module.exports = function(io) 
    const onePlaceMiddleware = require('./middleware/oneplace.js');
    io.use(onePlaceMiddleware);
;

【讨论】:

以上是关于Socket.io 命名空间和服务器不共享中间件?的主要内容,如果未能解决你的问题,请参考以下文章

Socket.io:命名空间、通道和合作

动态命名空间 Socket.IO

socket.io切换命名空间

Socket.IO:如何删除命名空间

在 MEAN.js 4.2 中使用 Socket.io 命名空间

使用 socket.io-client.java 库连接到 socket.io 命名空间