javascript - 带有 Socket.IO 和命名空间的 NodeJs-Cluster
问题描述
我正在构建一个浏览器游戏。原型已经完成,现在我正在考虑如何扩展和托管它。我已经有一个“游戏服务器”,它目前处理一个游戏会话。一个游戏会话由一个到 8 个玩家(最多)的 socketio 连接组成。
我想使用例如Node-Cluster在同一个 docker-container 中有多个“游戏服务器”,其中每个游戏服务器应该处理一个或多个游戏会话,以便可以使用 cpu 的所有内核。一个游戏会话仅由 8 个玩家使用,游戏会话应彼此隔离。
据我所知,Node-Cluster 使我能够让所有子进程共享同一个端口。我想为每个游戏会话设置一个名称空间(例如,玩家无论如何都连接到的浏览器中的 ID - 目标是:您获得一个发送给朋友以邀请他的 URL,类似于例如 skribble.io - https://localhost/?gameid=1234)。所以就我而言,加入命名空间基本上与加入游戏相同。
我的目标是拥有多个这些 docker-containers,并使用反向代理将传入连接路由到正确的容器,该容器处理游戏,在 url 中指定。但这里的问题是,我不知道如何将连接转发到集群的正确子进程。
所以最后它应该如下所示:
GameServerMaster [Maps ids to processes like: [ClusterNode1:[id1,id2,..]}
- GameServerClusterNode1
- GameSession1 [id1 io.off("/id1")]
- GameSession2 [id2 io.off("/id2)]
- ....
- GameServerClusterNode2
- GameSession3 [id3 io.off("/id3")]
- GameSession4 [id4 io.off("/id4)]
- ....
我找到了socket.io-redis,但这似乎有点过分了,因为没有广播 - 每个游戏都是孤立的。(而且我不想只为这个用例托管redis)
另外,我找到了sticky-session,但是通过使用它我不知道如何将传入的连接转发到正确的进程,我认为它只是对它们进行负载平衡,这很糟糕,因为它必须路由到那个实际上处理请求的游戏会话-但我认为无论如何我都需要类似的东西,或者我是吗?
我正在做的(或计划做的)是正确的方法吗?您在技术或架构方面有什么建议吗?
扔掉整个集群部分,只让 docker-container 处理一个“节点”来处理这些多个游戏会话会更好吗?
解决方案
我发现自己处于同样的情况,并提出了以下解决方案。
主意:
您使用不同端口上的集群模块创建新进程。使用主进程,您就像路由器一样。
例子:
在玩家加入房间之前,他询问路由器, (广播)123房间在哪里。路由器询问他的子进程 它们中的哪一个托管房间 123,并转发结果(例如端口 3001) 给客户。然后客户端连接到确切的进程。
问题:
如果多个子进程有相同的roomId,就会发生冲突, 但我想你会想办法避免这种情况, 即使发生这种情况的可能性非常低。
需要注意的是,这个解决方案是使用你机器的所有内核,而不是分发到多台机器的解决方案。
如果你想将它分发到多台机器上,你应该重新考虑 Redis 作为你的首选。
推荐阅读
- c# - 如何使用列名而不是c#中的列号仅检索csv的几列数据
- python - /usr/bin/python3:错误的解释器:符号链接的级别太多
- php - 在 PHP 中获取 XML 模式值
- javascript - 从Javascript中的对象数组中按键查找重复值
- c# - c# 切换到下一页时gridview中的分页问题
- node.js - npm 错误!arg 参数以非 ascii 破折号开头,这可能无效:[ '- g', 'appium' ]
- react-native - React Native Navigation v2 sideMenu 无法导航到屏幕
- javascript - html中div内部的新行自动修剪
- php - 如何记录 ZF1 助手以在我的 IDE 中自动完成
- plsql - PLSQL:在页面加载时有效地显示来自多个表的数据