Java多人游戏-网络概念

Java多人游戏-网络概念,java,sockets,networking,rmi,Java,Sockets,Networking,Rmi,对于一个学校项目,我们应该用Java创建一个多人游戏(应该是客户机/服务器),可以在互联网上玩(我们在学校编程,所以这不是家庭作业)。游戏是基于回合的,但是应该有聊天,当然是实时的。然而,我们中没有人有网络编程的经验,我读得越多,我的问题就越多 我的第一个想法是使用socket API来实现多人游戏部分。服务器等待来自客户端的新数据。但是,需要接收多种类型的数据,如聊天信息、移动等。此外,一旦连接到服务器,应发送一些初始数据(如玩家姓名)。服务器应该能够看到它接收到的消息类型,但是如何查看呢?我

对于一个学校项目,我们应该用Java创建一个多人游戏(应该是客户机/服务器),可以在互联网上玩(我们在学校编程,所以这不是家庭作业)。游戏是基于回合的,但是应该有聊天,当然是实时的。然而,我们中没有人有网络编程的经验,我读得越多,我的问题就越多

我的第一个想法是使用socket API来实现多人游戏部分。服务器等待来自客户端的新数据。但是,需要接收多种类型的数据,如聊天信息、移动等。此外,一旦连接到服务器,应发送一些初始数据(如玩家姓名)。服务器应该能够看到它接收到的消息类型,但是如何查看呢?我正在考虑创建一个带有字符串字段
type
的类
Message
。但在我的服务器代码中,我将得到如下代码:

if (message.type.equals("message")) {
  // code to execute for chat messages
} else if (message.type.equals("movement")) {
  // code to execute for movement
} else if () {
  // ...
} else {
  // ...
} // Please ignore syntax errors :P
当有很多不同类型的数据要发送时(将来也会有),这看起来不是最有效的方法。此外,这意味着服务器和客户端都应该具有此消息类/接口(重复代码)

其他游戏的东西呢?例如,玩家1将其角色移动到击败另一个角色的位置。玩家1的客户端计算此失败并应用正确的操作。但是应该向服务器发送什么呢?仅仅是新球员的位置还是失败?对于第一个选项,它意味着所有其他客户端都应该进行计算。这不会引起什么麻烦吗?由于我以前没有网络编程经验,我对如何做所有这些事情有点困惑

我还在Stackoverflow的另一篇文章中读到,RMI可能是一个更好的选择。在阅读了一些关于这方面的信息后,我理解了RMI是什么,但我仍然不能确定它是否是这个项目的一个好选择。有什么建议吗

如你所见,我对如何开始这个项目的网络部分有点困惑。我搜索了一些游戏编程书籍(当然是Java的),但没有一本是关于网络部分的。我也搜索过Java网络书籍,但这些书似乎关注的是技术,而不是良好的代码实践

如果有人知道一本好书或有一些正确方向的建议,我们将不胜感激


谢谢

你走在正确的道路上,但是没有什么事情需要澄清

如果你使用的是sockets,你已经知道你需要定义一个协议——一种交流动作和游戏状态的共同语言。套接字将允许您以几乎任何格式发送任何类型的数据。看起来您正在考虑序列化一个类消息来发送这种类型的消息,这是一个需要做的事情。如果您使用RMI(它有自己的协议),您的行为就像调用Java方法一样,但本质上您正在做类似的事情,序列化数据并通过套接字传递数据

在客户机和服务器之间共享代码并没有隐含的错误——事实上,大多数服务都是以某种形式进行的。您的客户机和服务器都可以使用公共库来定义传递的消息类。RMI使用方法存根来确定接口。各种Web服务都定义了调用方法的方式。一般的想法是只公开接口,而不是实现

关于您的代码,对于每种消息类型使用不同的消息子类可能会更简洁,并且您可以为每条消息添加额外的参数。然后,您可以拥有一个MessageProcessor类,如:

class MessageProcessor{
    void process(Move1Message m) {...}
    void process(Move2Message m) {...}
    ....

}
关于发送什么-一般原则应该是客户端负责将移动发送到服务器,它所做的任何其他事情都是额外的,因为服务器需要验证移动的合法性。服务器应该始终是游戏状态的决定者,以避免欺骗和错误的客户端实现


除非您对学习如何实现自己的协议或使用JavaSockets库感兴趣,否则使用RMI会更容易。您也可以使用SOAP、REST或任何其他协议,但我现在不会费心去想应该使用哪种协议。除此之外,我没有任何建议,尽管我认为有很多用于联网的代码示例。

使用套接字时,每个客户端都有自己的连接,服务器线程将在该连接上等待(不要忘记在客户端刷新流,否则您将永远等待)

每一行都是一条单独的消息,为了区分消息类型,您可以在每条消息的开头使用一个“标题”(开头是一个特定的3字符序列),例如
msg
mov
lgn
,并使用带开关的类似选择快速确定您得到的消息



使用RMI时,您可以让服务器保留一个manager对象(导出并在注册表中注册),客户机可以在该对象上请求“连接”-对象,该对象将与套接字实现中的连接相同,但您将能够为您想要做的每件事提供一个方法,尽管回调需要以其他方式完成(使用套接字,您已经准备好了连接)

“…在学校编程,所以这不是家庭作业”。经典。@CPerkins:我们应该在学校做这个项目,是的。我不是要求任何人来完成我的工作,只是询问如何实现这一点的建议。明白了,我认为你的问题是合理的,正如@Thomas所说,你不是在要求代码,但同样,我认为断言它不是“家庭作业”是幽默的。我真的希望你好运。@Bv202-“家庭作业”被理解为(至少在这里)任何以获取知识为主要目标,而创造的东西是次要目标的练习。(这可能是在课堂上,实验室里,