Android多人游戏网络对战

7
我正在编写一个Android多人游戏,基本上由一个服务器和客户端连接并交换消息组成。当玩家连接到服务器时,会向他/她返回一个玩家列表。然后,玩家可以选择要挑战的用户 - 当然,他必须从仅包含已连接用户的玩家列表中选择一个玩家。
当玩家1挑战玩家2时,需要从玩家1向服务器传输一条消息,然后服务器必须向玩家2发送一条消息,告知他有挑战。然后玩家2可以接受或拒绝挑战。
我可以使用以下技术来实现这一点:
  1. 使用Java套接字编程的自定义服务器/客户端。服务器基本上接受来自客户端的连接,为每个已连接的客户端生成一个新线程。这种方法存在以下问题:

    • 需要从客户端到服务器保持持久连接,浪费了安卓手机的电池寿命。但是这并不是很大的限制,因为电池消耗并不多。
    • 当我想开发另一个游戏时,我必须从头编写客户端/服务器代码 - 还要选择另一个端口来监听传入的连接 - 整个概念变得相当难以维护。
    • 我也担心这是否是正确的做法。为每个客户端生成另一个线程听起来很多,如果成千上万的客户端同时连接,可能会出现问题。但我猜PC游戏是这样做的。对于安卓系统就不太确定了。
  2. 使用Java REST jersey在HTTP之上构建客户端-服务器。如果服务器可以轻松地向客户端发送通知,这将是一个完美的解决方案。实际上有多个设计决策:

    • 客户端每隔几秒钟向服务器拉取任何新数据/通知 - 这非常不好,因为我们会遇到无响应、延迟等问题。
    • 客户端可以向服务器发送等待请求,因此只有在某些数据可用后,客户端才会收到响应。这更好,但当两个通知一个接一个地发送给用户时,仍可能产生延迟。第一个通知会立即发送,因为客户端已经建立了一个开放的连接,等待接收数据。但我们必须等待客户端启动另一个长时间的HTTP请求以接收第二个通知。当需要按顺序向特定客户端发送多个通知时,问题会变得更加严重。
    • 客户端可以启动HTTP流式传输,其中在处理请求时保留通信开放,因此服务器可以在希望时向客户端发送多个消息。这里的问题是我不知道这在安卓系统上运行得如何。我看过几个实现:
      • Java jersey + atmosphere:没有成功使其正常工作。这似乎是最有前途的,但我不想花太多时间在它上面,因为我甚至不确定它是否做到了我想要的。
      • Deacon:看起来相当不错,但在看完他们官方网页上的视频教程后,我不确定它能否完成我需要的功能。当玩家1挑战玩家2时,它能否向玩家2发送通知,让其知道比赛请求?
  3. 我很想知道其他多人游戏如何处理网络通信,如果两个玩家通过网络玩游戏。

  4. 我也愿意接受完全新的建议,以实现我想要的功能。我几乎可以编写任何东西,所以请不要犹豫,让我知道一些更困难的方式来实现网络通信。

让我也提一下,我很乐意实现完全特定的方法来适应我的情况,所以它可以是完成工作的任何东西,但我也在寻找更通用的客户端和服务器之间的通信方式。这样我就可以编写接口/其他内容并在其他Android游戏和应用程序中重复使用代码。
我希望我表达了问题,并能收到一些有价值的答案。
谢谢。
3个回答

2
您应该看一下XMPP。它是一个协议(最初为聊天程序创建),允许用户之间发送xml数据。
它具有分离的客户端-服务器关系,因此您可以专注于开发适用于手机的客户端应用程序,并根据需要选择不同的服务器。
有大量关于该协议的信息可用(我应该知道,我写了一篇关于在游戏应用程序中使用该协议的论文),但您可以通过在维基百科上查找来开始学习。 aSmack是用于创建Android XMPP客户端的库。进行一些调整以设置其并使其正常工作,但是一旦您完成,它就很好用。
编辑:与建议使用C2DM相关:
c2dm文档“发送大量C2DM消息”中:
“您是否过于频繁地发送C2DM消息?如果您需要在短时间内经常与应用程序通信,则C2DM可能不是最佳解决方案。相反,请考虑实施XMPP或自己的协议来交换消息,并仅使用C2DM发送初始通知。”

这可能是一个选择。我会研究一下。在谷歌搜索时,我也遇到了这个,只是觉得它不是最好的选择。我以为现在游戏使用的是一些不同的东西。所以你的建议是使用REST Java服务器+XMPP吗?是的,消息发送频率相当高 - 每秒钟一次。 - eleanor
它的表现出奇地好。但是你需要权衡传输/解释XML代码而不是特定值所带来的额外成本,与整个协议/库已经在数年内完成和测试的事实相对比。 - Jave
你好。我想再次感谢你的回答,但我还有一些额外的问题。 1)由于我的用户是通过XMPP连接的,他们需要先注册一个密码/用户名,这真的不太好。他们是否可以只指定一个用户名,就足以自动验证用户并将其放在玩家列表上? 2)我应该仅为当前会话(正在进行的会话)使用用户,还是应该为每个新用户名创建一个新用户?如果是后者,那么数据库的大小可能会变得非常大。欢迎任何想法。 - eleanor
我假设你想要某种玩家的身份识别,例如用户名?如果是这样,你可以让客户端使用用户名作为密码登录,或者随机生成一个密码,或者使用设备ID作为密码(根据协议需要密码)。如果您不需要保存用户的任何数据,例如,只使用用户来显示标识符(用户名),我认为最好的方法就是在他们完成游戏并注销时从服务器中删除用户。 - Jave
用户名/密码仅用于在网络中识别单个用户。您可以在抽象层下隐藏此信息,让您的服务器或客户端根据某些适当因素决定这些信息。最终如何控制取决于您。 - Jave

0

嗨。我在我的帖子中忘记提到这一点了。这不是一个选项,因为谷歌可能会开始收取发送的信息费用,而且我也不确定:每天可以发送多少条消息?此外,我还认为安卓网络游戏不使用这个,而是使用更复杂的东西。我可能错了。 - eleanor
您的发件人帐户将被分配默认配额,目前大约对应每天发送200,000条消息。 - Jave

0

我会投票支持一些消息传递技术 - 像activeMQ、rabbitMQ、zeroMQ或类似的技术。在服务器端,你可以使用Java或JavaScript(如node.js) - 这样的解决方案将提供最佳性能和最小延迟。

如果延迟不是那么关键,你也可以使用REST调用与JSON。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接