Socket.io & Redis - 适合 io 游戏的架构?

Posted

技术标签:

【中文标题】Socket.io & Redis - 适合 io 游戏的架构?【英文标题】:Socket.io & Redis - Proper architecture for an io game? 【发布时间】:2021-07-11 07:08:06 【问题描述】:

我正在使用带有 Redis 架构的基本 NodeJS 扩展,但我无法将其配置为适合实时多人游戏。

我的多人游戏应该有单独的大厅 - 因此当负载平衡器将用户放置在单独的服务器中时,同一个大厅中的玩家无法交流,除非我使用 Redis。问题是,我不能在服务器之间来回发送每一个动作,因为这会使 Redis 过载,并破坏服务器实例的可扩展性,因为现在我必须存储每一个每个 NodeJS 实例中的用户(检查冲突等),这违背了缩放的目的。除非我做错了什么?

基本 NodeJS/Redis 架构(对于带有大厅的 io 游戏效率低下?)

我还添加了一个单独运行的 Manager,它配置(创建/删除大厅)大厅,并通过 Redis 将信息发送到 Worker 实例,以便用户查看可用的大厅

我曾想过让每个 NodeJS 实例成为一个单独的大厅,但负载均衡器不能这样工作。此外,没有自动缩放。

我当前的架构,展示玩家(用户)

Red 供用户使用

Light Pink 用于通过 Redis 从其他服务器同步到自身的用户(否则,来自其他实例的玩家将彼此不可见。此外,将无法执行简单的更新,例如碰撞检测)

每个玩家都在自己选择的lobby中,并且是一个拥有XYangle和其他几个参数的对象

即使用户会加入Worker 2Worker 'n',我仍然需要将用户配置文件转发给其他工作人员,否则不在同一个Worker 上的用户将不会可见强>彼此。现在在这种情况下,它不是完全违背了缩放的目的吗?

要么我做错了什么,要么我确定必须有解决方案!

编辑

这是我到目前为止自己想出的,虽然不确定它是否合理

我几乎没有得到任何帮助,我们将不胜感激一些 cmets

【问题讨论】:

为什么需要同步每个worker中的所有用户? IIUC,您只需要另一个中间件,它将根据用户的大厅将用户分配给特定的工作人员。 @sonus21 检查玩家之间的碰撞以及发射的子弹。管理器是中间件。所以你认为我的架构还可以吗? 这个游戏是否有某种组,人们在一个组中玩并且每个组相互竞争?如果是这种情况,那么您的设计看起来不错,但您可以使用游戏 ID 进一步隔离。 @sonus21 是的,就是这样。尽管我终于让它工作了。我的问题是我没有意识到如果我在 1 个实例下运行所有​​内容,负载均衡器不会打开任何其他端口。所以我在没有负载均衡器的单独实例下运行工人。另外,我将在单独的实例中运行每个大厅。我不喜欢我必须手动添加/删除工人/大厅,但不能拥有一切 x) 已经足够了 感谢您验证我的架构是可靠的。输入一个答案,我会给你赏金,因为你真的是唯一一个试图提供帮助的人:) 【参考方案1】:

发表评论作为答案

根据评论,游戏是在团队之间进行的,每个团队都有一些成员,但游戏中的每个成员都必须了解其他成员(不仅是他们的团队成员),因为每个成员都必须了解所有其他成员游戏,用这个设计就好了。

虽然隔离应该在游戏级别进行,但每个游戏都应该有自己的一组大厅,每个大厅都包含所有玩家。

我们不必为每个大厅运行工作人员,而是可以为一个游戏使用一个工作人员,这将更新所有大厅数据。

此外,不应使用负载平衡器在工作人员之间分配玩家,而应在应用程序中使用中间件,如 GamePlayerManager/LobbyPlayerManager 来将玩家添加到特定大厅/从特定大厅中移除。

【讨论】:

以上是关于Socket.io & Redis - 适合 io 游戏的架构?的主要内容,如果未能解决你的问题,请参考以下文章

Django:使用 Redis PubSub、Node.js 和 Socket.io 的 JSON 通知

没有使用这个基本的 socket.io + redis 设置接收事件?

socket.io-redis 如何处理房间?

使用 Redis 扩展 Socket.IO,然后扩展 Redis 本身

如何在socket.io中重用redis连接?

将 pm2 的集群模块与 socket.io 和 socket.io-redis 一起使用