2012-10-18 51 views
2

基本上我想要一个在服务器上运行的Java,Python或C++脚本,监听播放器实例:加入,调用,下注,折叠,绘制卡片等,并且还有超时当球员离开或断开连接时。使用RPC的服务器上的多人纸牌游戏

基本上我希望每一个这些动作都是一个小的请求,这样玩家可以在同一台机器上与游戏服务器或机器上的进程通信。

消息传递的安全性不是问题,这是为了学习/研究/乐趣。

我的首要任务:

  1. 有当球员断开检测一个很好的方案,但也能占到网络延迟等启动/造成丢失前手。
  2. 速度。我将尽可能快地播放数百万手。在共享服务器实例
  3. 运行(我可能端口或需要根的东西有限)

我的问题:

  1. 侦听端口或使用套接字或HTTP端口80阿帕奇听脚本? (我对这些差异有点朦胧)。
  2. 任何良好的框架工作?
  3. 消息类型?我在想JSON或Protocol Buffers。
  4. 如何使它快速?

感谢球员 - 只是寻找一些指针和建议。我认为这是一个很酷的问题,有很多很好的东西可以学习。

+0

最重要的决定是使用哪个框架。如果这是一种学习体验,那么最重要的问题就是你想要学习什么。您对设计REST服务或Internet协议感兴趣吗?学习像Twisted或asio这样的中级框架,或者像Tomcat或JBoss这样的高级容器? (一般来说,容器意味着更少的代码,但更多的管理。)你有三种语言之间的任何偏好?但除此之外,还存在如下问题:客户端会话之间需要共享多少数据? – abarnert

+0

伟大的问题。我的最终目标是测试不同的AI和机器学习技术来玩游戏的“测试操场”。客户端不需要共享任何东西,他们只是互相玩耍并学习,使用服务器作为游戏管理员。 – lollercoaster

+1

你应该已经开始说明所有的玩家都是非人类玩家。为什么你需要一个网络呢?只需在同一台机器上实例化AI在游戏中的玩法并让它们通过内存交换状态。通过消除网络,您可以获得比通过在自己的机器上运行每个AI所获得的任何计算增益更高的性能。 AI计算甚至不需要平行。 –

回答

3

就框架而言,Ginkgo看起来很有希望用于构建网络服务(这就是您正在做的)。 Python非常简单,并且由gevent启用的异步性允许您执行异步事件,而不必担心回调。 gevent核心还允许您访问lot of building blocks

不是有很多通过端口通信服务的,你可能会考虑任何1)一个很好的消息队列,像RabbitMQ0mq,或2)分布式协调服务器,像Zookeeper

这就是说,你打算做什么是困难的,特别是如果你不熟悉的基础知识。了解这些基础知识是值得努力的。

起初不用担心速度。让它工作,然后让它扩展。当然,有一些方向可以让你在未来更容易扩展。 Zookeeper特别为您提供了易于实现的水平缩放原语(即共享负载的多个工作人员)。特别是,请参阅Zookeeper recipe book及其相应的python implementations(承蒙基于gevent的客户端库kazoo提供)。

不要忘记,“快速”也意味着优化您自己的开发时间,更快的迭代和更少的时间诅咒您的开发环境。所以使用Python,它可以让你现在快速启动并运行,如果你真的开始绑定CPU时间或内存使用,那么稍后再进行优化。 (通过这个特殊的应用程序,你更有可能绑定网络IO。)

+0

+1。关于横向扩展和快速开发的好解释是服务器端性能的关键。我不确定我会用Gingko代替更成熟的东西......但是基于gevent构建的完整框架的想法非常漂亮。如果有太多的东西需要学习,不必花费80%的时间学习如何连接回调。 – abarnert

+0

谢谢。银杏*的成熟度不如我想象的那么高,但这是我所知道的,它的文档比文档好(也就是它有* docs),并且根据我自己的经验,它足够简单,可以用最少的样板。我很高兴能够通过文档了解任何其他基于gevent的服务框架。 :) –

+0

我的观点是,我不知道任何其他基于gevent的框架比银杏更好,所以我*可能*使用银杏,尽管它并不像我想的那么成熟,我仍然很谨慎。无论如何,你已经说服我去玩它了,你的回答并不只是说它“看起来很有希望”,所以你的答案绝对值得我给的+1。 – abarnert

2

还有什么?也许一杯咖啡去与您的问题:-)

从头开始回答您的问题需要几本书的价值的文本从主题从基本的TCP/IP网络到可扩展的架构,但我会尽力不过给你一些指导。

问题:

  1. 侦听端口或使用套接字或HTTP端口80阿帕奇听脚本? (我对这些差异有点朦胧)。

我敢打赌,如果你不清楚每一个的定义,也许设计一个实现一个服务,将“尽可能快地播放数百万这些手”是有点嗯,过深远?但是,不要因为他们说“无知是幸福”而阻止你。

  1. 任何良好的框架工作?

我认为你的项目是一个很好的候选Node.js.主要原因是Node.js相对可扩展性强,并且很好地隐藏了可伸缩性所需的复杂性。 Node.js有缺点,只是谷歌搜索'Node.js可扩展性批判'。 对Node的要点。与使用更通用的框架不同的是,可扩展性是困难的,没有办法绕过它,并且Node.js的高级别和特定性为解决问题提供了更少的选项。 另一个缺点是Node.js是JavaScript而不是Java或Phyton,如你所愿。

  1. 消息类型?我在想JSON或Protocol Buffers。

我不认为会有很多客户端和服务器之间的流量,所以它并不重要,因为它更流行,我会去与JSON。

  1. 如何使它快速?

真正的问题是如何使其具有可扩展性。运行人类与人类纸牌游戏不是计算密集型的,因此在达到任何计算限制之前,您可能会耗尽I/O容量。 克服这些限制是通过在机器间传播负载来完成的。在多玩家游戏中常见的做法是有一个列表服务器,它提供到相同游戏服务器的链接,每个服务器有预定数量的可供玩家使用的插槽。 这是经纪人机构的一种变体,即经纪人机器根据用户的忙碌情况为客户指定一台工作机。在游戏用户希望能够选择他们的服务器,以便他们可以和他们的朋友一起玩。

相关:

  1. 有当球员断开检测一个很好的方案,但也能占到网络延迟等启动/造成丢失前手。

由于这是人类的时间尺度(以秒为单位而不是以毫秒为单位),客户端应该每隔10秒发送一次keepalive,例如说30秒会话超时。 Keepalive会在您的应用程序协议中使用JSON消息,而不是HTTP,它是较低级别的并由框架处理。 框架本身应该为您提供HTTP 1.1连接管理/池,它允许多个http会话(请求/响应)通过相同的连接,但不要求客户端始终连接。这是可靠性和速度之间的一个很好的折衷,对于基于回合的纸牌游戏应该足够好。

1

老实说,我会从经典的LAMP开始。拿出一个股票Apache服务器和一个mysql数据库,并把你的Python脚本放在cgi-bin目录下。他们发送和接收JSON而不是HTTP的事实并没有太大的区别。

当然,这显然不会是最灵活或可扩展的解决方案,但它会迫使您尽早面对实际问题。

你将遇到的第一个问题是游戏状态。你声称没有共享状态,但这并非对 - 卡组中的牌,桌上的赌注,轮到它的状态,这是所有状态,在多个玩家之间共享,在服务器上进行管理。这些命令中的任何一个还能工作吗?所以,你需要一些方法来在CGI脚本的不同实例之间共享状态。经典的解决方案是将状态存储在数据库中。

当然,您还需要首先处理用户会话。细节取决于您选择哪种会话管理方案,但最大的问题是如何将断开/超时从较低级别传播到应用程序级别。如果有人把20美元放在桌子上然后断开连接,会发生什么?你必须考虑所有可能的用例。

接下来,您需要考虑可伸缩性。你想要数百万游戏?那么,如果有一个包含所有游戏状态的单个数据库,则可以根据需要在它之前安装尽可能多的Web服务器 - John Doe可能在server1上,而Joe Schmoe在server2上,但他们可以在同一个游戏中。另一方面,只要你有办法迫使同一个游戏中的人在同一台服务器上见面,你就可以为每个服务器分配一个数据库。哪一个更有意义?无论哪种方式,你如何负载平衡服务器之间。 (你不仅希望让他们全部忙碌,你想避免4个玩家都准备好去的情况,但他们在3个不同的服务器上,所以他们不能玩对方......)。

这个过程的最终结果将是一个服务器的巨大混乱,运行在你希望的容量的1%处,你不知道如何维护。但是你会更详细地考虑你的问题空间,并且你也学会了服务器开发的基础知识,从长远来看这两者可能都是更重要的。

如果你有足够的时间,我会把所有东西都从头开始重新编写,通过设计一个自定义的TCP协议,在Twisted中实现一个服务器,保持内存中的游戏状态,以及编写简单的自定义代理而不是标准的负载均衡器。

+0

是的,我现在的计划是Django/python + mysql + json over HTTP,只是想知道。很酷,谢谢。什么是经纪人?谷歌/维基百科没有那么有用。基本上只是一个Web服务,保持连接/有会话的客户的状态? – lollercoaster

+1

对不起, “经纪人”是一个非常超负荷的术语。我的意思是,它将有足够的关于玩家和游戏的信息,可以将其从简单的负载平衡扩展到例如重新加入游戏,寻找朋友等,和/或游戏特定的负载平衡(例如,如果3玩家正在等待服务器2上的第4个,下一个连接进入服务器2,甚至服务器1的负载更少)。 – abarnert