将用户添加到连接到具有node、socketio和redis的其他服务器的房间

vtwuwzda  于 2021-06-10  发布在  Redis
关注(0)|答案(1)|浏览(403)

我正在node.js中为一个基于swift的ios应用程序编写服务器端代码。目前,该代码在一个ec2示例上运行时可以工作,但我正在设置一个网络负载均衡器,以便它可以更适当地扩展传入的用户流量。我决定实现这一点的最简单方法是使用redis适配器。现在,我的server.js文件包括:

const app = new Koa();
const server = http.createServer(app.callback));
const io = require('socket.io')(server);
const redisAdapter = require('socket.io-redis');
io.adapter({ host: 'my-elasticache-redis-endpoint', port: 6379 })

根据文档,从代码的Angular 来看,这似乎是让redis在项目中真正工作所必需的唯一步骤,但我可能遗漏了一些东西。从体系结构的Angular 来看,我在目标组上启用了粘性会话,并设置了两个服务器,都运行此代码。此外,如果我打印出socket io信息,我可以看到它已经充分连接到redis端点。
问题如下。假设我有两个人,人a和人b,每个人都连接到不同的服务器。应用程序的功能应该是这样的:
人员a将人员b添加到插座室。然后服务器向该房间中的每个人发出一个事件,表示人员b已经加入,因此前端可以相应地做出响应。
这是通过以下功能完成的:

protected async r_joinRoom(game: GameEntity, player: PlayerEntity): Promise<void> {
    return new Promise((res, rej) => {
      let socket: any;
      socket = this._io.sockets.connected[player.socket_id];
      if (!socket) {
        socket = this._socket;
      }
      socket.join(`game/${game.id}`, (err: any) => {
        if (err) {
          return rej(new GameError(`Unable to join the room=${game.id}.\n${err}`));
        }
        res();
      });
    });
  }

这里的前提是,人b是一个玩家,作为一个玩家,他有一个相关的socket id,服务器正在跟踪这个id。不过,我认为问题在于 socket = this._io.sockets.connected[player.socket_id]; 找不到已连接的播放机,因为从技术上讲,他已连接到其他服务器。打印出的套接字显示为null,如果我随后在播放器b所连接的服务器上运行完全相同的函数,那么他加入房间就没有问题了。因此,当发出的事件发生在将人b“添加”到房间之后时,只有人a的电话获得事件,而不是b。这是我的redis设置的问题吗?或者有没有办法让所有连接的客户端都连接到运行node.js应用程序的服务器上?

6gpjuf90

6gpjuf901#

最后我回答了自己的问题。添加到房间时,必须直接从适配器执行。从文件上看,这意味着我会 socket.join...

io.of('/').adapter.remoteJoin('<my-id>', 'room1', (err) => {
  if (err) { /* unknown id */ }
  // success
});

使用这个remotejoin函数很管用

相关问题