# 消息 (/zh-CN/api-reference/rtm/unity/message)

> For AI agents: see the complete documentation index at [llms.txt](/llms.txt).

收发消息是 RTM 服务的基础功能之一，任何使用 RTM 服务发送的消息将会在 100 ms 以内送达到任何一个在线订阅用户端上，你可以一次只给一个人发消息，也可以一次给多人广播消息，这取决于你的使用方式。

RTM 有两种频道类型，分别是 Message Channel 和 Stream Channel。两种频道中消息的传递方式和需要调用的方法不同，区别如下：

- **Message**：实时频道，消息通过频道传递，可扩展性强。本地用户可以调用 `PublishAsync` 方法在频道中发送消息，远端用户可以调用 `SubscribeAsync` 方法订阅频道并接收消息。
- **Stream**：流传输频道，用户需要先加入频道，然后加入 Topic，消息通过 Topic 传递。本地用户可以调用 `PublishTopicMessageAsync` 方法在 Topic 中发送消息，远端用户可以调用 `SubscribeTopicAsync` 方法订阅 Topic 并接收消息。

本文介绍如何在 Message Channel 中收发消息。

想要了解更多收发消息的信息可以查看：

- [消息](/zh-CN/realtime-media/rtm/build/messaging/send-message)

## PublishAsync [#publishasync]

### 接口描述 [#接口描述]

你可以直接调用 `PublishAsync` 方法向订阅该频道的所有在线用户发送消息。即使没有订阅频道，也能在频道中发送消息。

:::info[信息]
以下做法可有效提升消息收发的可靠性：

- 消息负载限制在 32 KB 以内，否则发送会失败。
- 向单个频道发送消息的速率上限为 60 QPS。如果发送速率超限，将会有部分消息被丢弃。在满足要求的情况下，速率越低越好。
:::

成功调用该方法后，订阅了该频道并开启了事件监听的其他用户会通过 `OnMessageEvent` 收到这条消息，详见[事件监听](/zh-CN/api-reference/rtm/unity/configuration#事件监听)。

### 接口方法 [#接口方法]

你可以通过以下方式调用 `PublishAsync`[1/2] 和 `PublishAsync`[2/2] 方法：

```csharp tab="PublishAsync[1/2]"
// PublishAsync[1/2]
RtmResult<PublishResult> PublishAsync(string channelName, byte[] message, PublishOptions option);
```

```csharp tab="PublishAsync[2/2]"
// PublishAsync[2/2]
RtmResult<PublishResult> PublishAsync(string channelName, string message, PublishOptions option);
```

|     参数      |        类型        | 是否必填 | 默认值 | 描述             |
| ---------- | --- | ----- | --- | --------------- |
| `channelName` |       string       |   必填   |   -    | 频道名称。       |
|   `message`   |       string       |   必填   |   -    | 消息负载。       |
|   `option`    | `PublishOptions` |   必填   |   -    | 发布消息的选项。 |

<a id="options"></a>
`PublishOptions` 包含以下属性：

|     参数     |  类型  | 是否必填 | 默认值 | 描述               |
| --------- | --- | ----- | --- | ----------------- |
|   `channelType`   |  `RTM_CHANNEL_TYPE`  |   必填   |  -   | 频道类型。详见 [`RTM_CHANNEL_TYPE`](/zh-CN/api-reference/rtm/unity/enumv#channeltype)。 |
| `customType` | string |   选填   |   -    | 用户自定义字段。   |

### 基本用法 [#基本用法]

```csharp
var message = "Hello World";
var channelName = "my_channel";
var options = new PublishOptions();
options.customType = "PlainText";

var (status,response) = await rtmClient.PublishAsync(channelName, message, options);
if (status.Error)
{
    Debug.Log(string.Format("{0} is failed, ErrorCode: {1}, due to: {2}", status.Operation, status.ErrorCode, status.Reason));
}
else
{
    Debug.Log("Publish Message Success!");
}
```

### 返回值 [#返回值]

`PublishAsync` 操作返回一个 `RtmResult<PublishResult>` 类型数据结构的返回值，其中包含：

|    属性    |       类型        | 描述         |
| ------- | ----- | ------------ |
|  `Status`  |   `RtmStatus`    | 无论操作是否成功，都返回一个 `RtmStatus` 类型的数据结构，其中包含本次操作的状态。  |
| `Response` | `PublishResult` | 操作成功后，返回一个 `PublishResult` 类型的数据结构，其中包含本次操作的执行结果。 |

`RtmStatus` 包含以下属性：

|    属性     |  类型  | 描述               |
| ------- | -- | ------- |
|   `Error`   |  bool  | 本次操作是否出错。 |
| `ErrorCode` | string | 错误码             |
| `Operation` | string | 本次操作类型。     |
|  `Reason`   | string | 本次操作出错原因。 |

你可以通过检索 `errorCode` 字段的[错误码](/zh-CN/realtime-media/rtm/build/troubleshooting)了解错误原因，并找到对应的解决方法。

`PublishResult` 包含以下属性：

|     属性      |  类型  | 描述                     |
| ---------- | --- | --------- |
| `ChannelName` | string | Message Channel 频道名称 |

<a id="接收消息"></a>
## 接收消息 [#接收消息]

RTM 提供消息、状态、事件变更等信息的事件通知。通过设置事件监听，你可以接收已订阅频道中的消息和事件。

关于如何添加和设置事件监听，详见[事件监听](/zh-CN/api-reference/rtm/unity/configuration#事件监听)章节。
