Socket.io 有多个命名空间?

Socket.io with multiple namespaces?

我有一个监听特定路由 ID 的路由。

/**
 * Chat app routes.
 */
app.get('/games/:id', gameChatController.chatRoom);

根据路线id我可以确定聊天内容是什么游戏。

我的问题是如何使用它传递给 socket.io?

bin/www

/*
* setup socket.io, and socket-session
*/
var socketIO = require('socket.io');
var io = socketIO(server);
var SessionSocket = require('session.socket.io');
var sessionSockets = new SessionSocket(io, app.sessionStore, app.cookieParser);
var setEvents = require('../events');
setEvents(sessionSockets);

events/index.js

'use strict';
var redis = require('redis');
var sub = redis.createClient();
var pub = redis.createClient();
sub.subscribe('chat');

module.exports = function(io) {

    // here io basically is sessionSockets

    // TODO: Set a namespace, make it dynamic
    var theRoom = 'fifa14';
    var namespaceRoom = io.of('/'+theRoom);

    namespaceRoom.on('connection', function(err, socket, session) {
        if (!session.user) return;

        console.log(socket);

    }
}

所以我要问的是如何构建它以便我可以轻松传递应用程序的当前状态以匹配套接字命名空间的状态,这样特定游戏中的用户只能在其中聊天?

因为我觉得像下面这样的事情效率不高

controllers/chat.js

/**
 * GET /
 * ChatRoom page.
 */
exports.chatRoom = function(req, res) {

/*
* setup socket.io, and socket-session
*/
var socketIO = require('socket.io');
var io = socketIO(server);
var SessionSocket = require('session.socket.io');
var sessionSockets = new SessionSocket(io, app.sessionStore, app.cookieParser);
var setEvents = require('../events');
// so here I can pass the route parameters, not efficient!
setEvents(sessionSockets, req.params.id);

  res.render('chatRoom', {
    roomName: req.params.id
  });
};

所以现在我可以将新的游戏 ID 传递到 setEvents(),但我认为这样会更好。

'use strict';
var redis = require('redis');
var sub = redis.createClient();
var pub = redis.createClient();
sub.subscribe('chat');

module.exports = function(io, gameId) {

    // here io basically is sessionSockets

    // Now I can pass the proper id
    var namespaceRoom = io.of('/'+gameId);

    namespaceRoom.on('connection', function(err, socket, session) {
        if (!session.user) return;

        console.log(socket);

    }
}

很难准确地说出你在这里问的是什么问题,所以我将从概念上解释它是如何工作的。

您的聊天应用程序路由是针对每个客户的。每个客户分别走那条路线。如果你想与来自同一客户端的未来传入 socket.io 连接共享一些状态,你有两种主要方法:

  1. 当路由被命中时,你可以设置一个cookie,并将特定的状态放在cookie中。然后,当传入的 socket.io 连接到达时,您可以检查 cookie 以查看此套接字应该转到哪个聊天室。

  2. 当路由被命中时,您可以设置一个会话 ID(作为 cookie),然后将一些状态存储在某种会话存储中。然后,当来自该客户端的传入 socket.io 连接到达时,您从 cookie 中获取会话 ID,然后您可以查看会话存储以查看此 socket.io 连接的状态。

您不能将任何内容直接传递给 socket.io,因为传入的 http 路由和传入的 socket.io 连接都是针对每个客户端的,并且不是同时进行的,因此您无法设置任何全局状态关于一个特定的未来 socket.io 联系。相反,您使用客户端 cookie 在该特定客户端上设置某些状态或建立会话 ID,以便该状态可以在您的会话存储中。