在 Session 与 Listener 的接口中，会看到 Entity 和 Message。它们有什么区别？

### 1、比较


| 比较         | Entity        | Message                                         | 备注  |
| -------- | -------- | ----------------------------- | -------- |
| 相同         | 是接口       |  是接口                                           | 都会有不同的实现类   |
| 不同         |                 |  message = sid + event + entity         | 可以说 message 包函了 entity   |
| 用途        | 用于发送     | 用于接收与答复                                |   |


消息传输时，会把 sid, event, entity 放到帧里进行传输（协议以帧为单位进行传输）。帧的结构为：

```
frame: {flag, message: {sid, event, entity: { meta, data}}}
```

### 2、三个常见的 Entity （为了发送方便）


| 实体 | 说明 | 备注 |
| -------- | -------- | -------- |
| EntityDefault     | 默认实体     | 一般用于传二进制数据      |
| FileEntity          | 文件实体（基于 EntityDefault 扩展）     | 一般用于传输文件     |
| StringEntity      | 字符串实体（基于 EntityDefaul 扩展）     | 很常用（比如你发个 json 消息）     |

也可以基于 Entity 接口定制！


### 3、接口（以 Java 为例）

* Entity

```java
public interface Entity {
    /**
     * 获取元信息字符串（queryString style）
     */
    String metaString();

    /**
     * 获取元信息字典
     */
    Map<String, String> metaMap();

    /**
     * 获取元信息
     */
    String meta(String name);

    /**
     * 获取元信息或默认
     */
    String metaOrDefault(String name, String def);

    /**
     * 获取元信息并转为 int
     */
    default int metaAsInt(String name) {
        return Integer.parseInt(metaOrDefault(name, "0"));
    }

    /**
     * 获取元信息并转为 long
     */
    default long metaAsLong(String name) {
        return Long.parseLong(metaOrDefault(name, "0"));
    }

    /**
     * 获取元信息并转为 float
     */
    default float metaAsFloat(String name) {
        return Float.parseFloat(metaOrDefault(name, "0"));
    }

    /**
     * 获取元信息并转为 double
     */
    default double metaAsDouble(String name) {
        return Double.parseDouble(metaOrDefault(name, "0"));
    }

    /**
     * 放置元信息
     * */
    void putMeta(String name, String val);

    /**
     * 获取数据
     */
    ByteBuffer data();

    /**
     * 获取数据并转为字符串
     */
    String dataAsString();

    /**
     * 获取数据并转为字节数组
     */
    byte[] dataAsBytes();

    /**
     * 获取数据长度
     */
    int dataSize();

    /**
     * 释放资源
     */
    void release() throws IOException;
}
```

* Message

```java
public interface Message extends Entity{
    /**
     * At player name
     *
     * @since 2.3
     */
    default String atName() {
        return meta("@");
    }

    /**
     * 范围开始
     * */
    default int rangeStart(){
        return metaAsInt(EntityMetas.META_RANGE_START);
    }

    /**
     * 范围大小
     * */
    default int rangeSize(){
        return metaAsInt(EntityMetas.META_RANGE_SIZE);
    }


    /**
     * 是否为请求
     */
    boolean isRequest();

    /**
     * 是否为订阅
     */
    boolean isSubscribe();

    /**
     * 获取消息流Id（用于消息交互、分片）
     */
    String sid();

    /**
     * 获取消息事件
     */
    String event();

    /**
     * 获取消息实体（有时需要获取实体）
     */
    Entity entity();
}
```


