什么是实时游戏服务器最高效的Java实现?

10

我计划构建一个Java服务器,用于处理客户端之间的实时游戏通信。什么样的Java实现方式最能高效、准确地在��户端和服务器之间进行通信(比如每秒5-15个数据包)?我知道有许多种Java网络API(即ObjectInputStream和ObjectOutputStream、DatagramPacket、KyroNet等),但我不确定哪种是这种情况下最有效和/或常用的实现方式。我认为大多数实时游戏使用UDP通信方法,但我了解其中存在的可靠性问题。是否有UDP实现方式具备某种形式的流量控制?无论如何,先提前感谢您!


1
每秒15个数据包并不算是高速。每秒100,000个数据包才算是高速。 - Erik
我正在阅读一篇关于Valve如何制作他们的Source服务器的文章,他们说他们的平均每秒发送20-30个数据包。由于我正在构建一个规模更小的游戏,所以我不需要那么多。我认为在一秒钟内发送100,000个数据包会占用相当大的带宽,你不觉得吗? - Brian
丢失一个数据包是否有任何重要性?如果没有,那么我会选择使用带有非常简单校验和的UDP(DatagramPacket),只需丢弃坏的数据包即可。不过,建立连接本身最好还是用TCP。 - veiset
当然,丢失数据包总是不好的,可能需要客户端对此进行补偿,但服务器和客户端同时建立TCP和UDP连接并不罕见。也就是说,TCP连接有助于维护快速移动的UDP连接的完整性? - Brian
你自己的翻译!以上内容都不够高效。UDP 可能很酷,但随着更多玩家的互动,它会开始消失。每个客户端20-30可能听起来合适。我会选择基于自定义构建的TCP NIO。 - bestsss
为什么不直接使用NIO,但是对于这样慢的速度,服务器会做多少工作?如果可维护性很重要,您可能需要考虑Groovy或Scala等语言,例如,您会受到性能影响,但这两种语言都有好处,并且可以处理这样慢的速度。 - James Black
2个回答

12

需要考虑以下几点:

  • Java NIO非常好,可以处理您所需的吞吐量/延迟。不要使用任何旧的网络/序列化框架和API。
  • 延迟非常重要。你基本上想要在NIO上添加最小的层,以允许你发送非常快速、小型、个别的消息,同时保证开销最小。
  • 根据游戏的不同,您可能需要使用TCP、UDP或两者。对于重要的消息,请使用TCP;对于不是严格必要的或将被未来更新取代的消息(例如FPS中的位置更新),请使用UDP。
  • 一些人在实时游戏中通过UDP实现了自己类似TCP的消息传递协议。这可能比它的价值更麻烦,但如果您确实需要针对特定类型的通信进行优化,则应该考虑此选项。
  • 对于实时游戏,你几乎总是进行自定义序列化(例如只发送对象位置的增量而不是完整更新)-因此确保您的框架支持此功能。

考虑到这些,我建议您选择以下之一:

  • Kryonet - 轻量级、可定制、专为此类目的而设计。
  • Netty - 稍微更面向企业,但非常强大、健壮和可扩展。
  • 基于NIO自己开发-如果您想要真正精细的控制,这可能有些棘手。我以前做过这个,但回想起来,我可能应该选择Kryonet或Netty。

祝你好运!


1
顺便提一下,在UDP+TCP之间进行同步是一个难以解决的问题,它可能成为服务器“黑客”问题的严重来源。我认为,自定义NIO并不那么困难,但我猜这个问题在第一时间就不会被问到。同时,了解何时使用直接缓冲区也需要经验,我的建议是每个客户端使用一个直接缓冲区,并设置套接字snd缓冲区大小的容量。 - bestsss
只有一个问题,使用较新的NIO API的主要优势是什么?当然,它是较新的,所以可能更好,但与使用传统的Sockets和ServerSockets相比有什么区别? - Brian
NIO的主要优势在于它利用操作系统中的低级构造 - 因此您可以使用更低的开销进行数据传输,使用选择器处理事件驱动的异步响应等。 - mikera
fast-serialization + fast-cast + netty 是用于集群高性能应用程序的不错组合 - R.Moeller

1

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