10

修改后的问题:

好的,所以我正在尝试将其合并到我自己的定制游戏中。我了解 Netty 服务器和客户端如何连接的过程。我也了解解码器和编码器在理论上是如何工作的。但这是我仍然想了解的。

我的服务器进程:

Server boots up -> Client starts
Client requests connection -> Server accepts
Server instructs client connection is good -> Client continues to the login screen
(Ignoring any type of security protocol)
Client sends username and password over Channel
Server gets username and password checks it in the database or file
Server pushes -> yes or no
if yes Server sends player stats
if no Server creates new player

在这个过程之后,我知道我需要一个世界处理程序,以便每个人都能近乎实时地看到更新。现在我不知道如何为这些东西实现解码器。

我真的很想看一些例子,并解释它们是如何实现的。最好有一些说明.... 注意:我并不是说要为我解决这个问题,而是告诉我如何处理不同的信息。请提供最佳实践和标准......

4

1 回答 1

4

人们编写自己的编码器/解码器(编解码器),因为 Netty 没有强加或定义应用程序级协议,因此您可以自由编写自己的协议。例如,您定义的编解码器集是一个协议,可以是基于字符串和某种二进制格式(如 Protobuf)之间的任何协议。Netty 为您提供了方便的编解码器(您使用的是示例)。

我认为这是为了防止流过早被切断?

通常,当您发送/接收流时,您需要将其分解为固定长度的块(称为帧)。一种流行的方法,自 Internet 诞生以来就一直在使用,即使用块的长度(通常是 4 字节 int)作为从流中读取的第一个字段。因此,如果第一个 int 的值是 20,那么您知道接下来的 20 个字节是有效负载(数据),第 21 个字节是另一个长度的第一个字节。这种方法的优点是它允许可变长度的块。但你不限于此。例如,如果您计划编写一个使用具有预定义长度(带有填充)的字符串的协议,那么您将编写或者甚至更好地使用适合它的 Netty 当前编解码器。

有一次,我实现了一个包含三个解码器的协议,这些解码器将按以下顺序执行:

  1. 接收流并将其分解为长度前缀帧;
  2. 将每一帧转换为字符串;
  3. 使用 Jackson libray 将字符串转换为预定义的 Java 对象。

编码器只会做同样的操作,但会倒退。不幸的是,我丢失了原始代码,但我会尽快重写它。

但是流如何知道流是一个字符串或一系列 int 或一系列双精度数?你怎么告诉它区别是问题?

简短的回答:它不知道。您必须在编解码器中对此信息进行编码。例如,您可以使用操作码作为有效负载中的第一个字段,说明有效负载是字符串、双精度、整数或两者的任意组合。

基本上,Netty 提供了一个流,你可以随意解码。例如,如果您正在读取一系列 long(8 个字节),那么您将编写一个每次从流中读取 64 个字节的编解码器,因为每个都代表一个 long。Netty 提供开箱即用的编解码器,因此您无需每次都重新发明轮子。

于 2012-12-20T13:42:06.547 回答