消息
收发消息是 RTM 服务的基础功能之一,任何使用 RTM 服务发送的消息将会在 100 ms 以内送达到任何一个在线订阅用户端上,你可以一次只给一个人发消息,也可以一次给多人广播消息,这取决于你的使用方式。
RTM 有 3 种频道类型,分别是 Message Channel、User Channel 和 Stream Channel。3 种频道类型的主要区别如下:
- Message Channel:实时频道,消息通过频道传递,可扩展性强。本地用户可以调用
publish
方法,将channelType
参数设为message
,并将channelName
参数设为频道名称,即可在频道中发送消息。远端用户可以调用subscribe
方法订阅频道并接收消息。 - User Channel:向指定用户发送点对点消息。本地用户可以调用
publish
方法,将channelType
参数设为user
,并将channelName
参数设为对方的userId
,即可向指定用户发送消息。指定用户可以通过message
事件通知来接收消息。 - Stream Channel:流传输频道,用户需要先加入频道,然后加入 Topic,消息通过 Topic 传递。本地用户可以调用
publishTextMessage
方法在 Topic 中发送消息,远端用户可以调用subscribeTopic
方法订阅 Topic 并接收消息。
本文介绍如何在 Message Channel 和 User Channel 中收发消息。
想要了解更多收发消息的信息可以查看:
publish
接口描述
你可以直接调用 publish
方法向订阅该频道的所有在线用户发送 String 型消息。即使没有订阅频道,也能在频道中发送消息。
以下做法可有效提升消息收发的可靠性:
- 消息负载限制在 32 KB 以内,否则发送会失败。
- 向单个频道发送消息的速率上限为 60 QPS。如果发送速率超限,将会有部分消息被丢弃。在满足要求的情况下,速率越低越好。
成功调用该方法后,SDK 会触发 message
事件通知。订阅了该频道并且开启了事件监听的用户将会收到该事件通知,详见事件监听。
接口方法
你可以通过以下方式调用 publish
方法:
Future<(RtmStatus, PublishResult?)> publish(
String channelName,
String message,
{
RtmChannelType channelType = RtmChannelType.message,
String? customType
}
);
参数 | 类型 | 必填 | 默认值 | 描述 |
---|---|---|---|---|
channelName | String | 必填 | - |
|
message | String | 必填 | - | 消息负载。 |
channelType | RtmChannelType | 选填 | message | 频道类型。详见 RtmChannelType 。 |
customType | String | 选填 | - | 用户自定义字段。仅支持字符串型。 |
接口方法
示例 1:向指定 Message Channel 发送 String 消息
var message = {
type: "poll",
question: "Which option is right?",
answers: {
A: "Apple",
B: "Banana",
C: "Blackberry"
},
sender: "Max"
}
var payload = json.encode(message);
var (status,response) =
await rtmClient.publish("myChannel", payload, channelType:RtmChannelType.message, customType:"poll");
if (status.error == true) {
print(status);
} else {
print(response);
}
示例 2:向指定 User Channel 发送 String 消息
var message = {
type: "chatInvite",
channel: "this is the channel you are being invited too",
message: "Hi Tony, welcome to the team!"
}
var payload = json.encode(message);
var (status,response) =
await rtmClient.publish("userId", payload, channelType:RtmChannelType.user, customType:"chatInvite");
if (status.error == true) {
print(status);
} else {
print(response);
}
返回值
调用该方法,会返回 Future<(RtmStatus, PublishResult?)>
类型的元组数据。
-
无论该方法是否调用成功,元组的第一项都会返回一个
RtmStatus
类型的数据,其中字段定义如下:Dartclass RtmStatus {
bool error; // 本次操作是否出错。
String errorCode; // 本次操作错误码。
String operation; // 本次操作的 API。
String reason; // 本次操作错误原因简述。
}你可以通过检索
errorCode
字段的错误码了解错误原因,并找到对应的解决方法。 - 如果该方法调用成功,元组的第二项将返回一个
PublishResult
类型的数据,当前不包含任何字段。
publishBinaryMessage
接口描述
你可以直接调用 publishBinaryMessage
方法向订阅该频道的所有在线用户发送 Binary 型消息。即使没有订阅频道,也能在频道中发送消息。
以下做法可有效提升消息收发的可靠性:
- 消息负载限制在 32 KB 以内,否则发送会失败。
- 向单个频道发送消息的速率上限为 60 QPS。如果发送速率超限,将会有部分消息被丢弃。在满足要求的情况下,速率越低越好。
成功调用该方法后,SDK 会触发 message
事件通知。订阅了该频道并且开启了事件监听的用户将会收到该事件通知,详见事件监听。
接口方法
你可以通过以下方式调用 publishBinaryMessage
方法:
Future<PublishResult> publishBinaryMessage(
String channelName,
Uint8List message,
{
RtmChannelType channelType = RtmChannelType.message,
String? customType
}
);
参数 | 类型 | 必填 | 默认值 | 描述 |
---|---|---|---|---|
channelName | String | 必填 | - |
|
message | Uint8List | 必填 | - | 消息负载。 |
channelType | RtmChannelType | 选填 | message | 频道类型。详见 RtmChannelType 。 |
customType | String | 选填 | - | 用户自定义字段。仅支持字符串型。 |
接口方法
示例 1:向指定 Message Channel 发送 Binary 消息
var payload = [1,2,3,4];
var (status,response) = await rtmClient.publishBinaryMessage(
"myChannel",
payload,
channelType:RtmChannelType.message,
customType:"UINT8LIST"
);
if (status.error == true) {
print(status);
} else {
print(response);
}
示例 2:向指定 User Channel 发送 Binary 消息
var payload = [1,2,3,4];
var (status,response) = await rtmClient.publishBinaryMessage(
"myChannel",
payload,
channelType:RtmChannelType.message,
customType:"UINT8LIST"
);
if (status.error == true) {
print(status);
} else {
print(response);
}
返回值
调用该方法,会返回 Future<(RtmStatus, PublishResult?)>
类型的元组数据。
-
无论该方法是否调用成功,元组的第一项都会返回一个
RtmStatus
类型的数据,其中字段定义如下:Dartclass RtmStatus {
bool error; // 本次操作是否出错。
String errorCode; // 本次操作错误码。
String operation; // 本次操作的 API。
String reason; // 本次操作错误原因简述。
}你可以通过检索
errorCode
字段的错误码了解错误原因,并找到对应的解决方法。 - 如果该方法调用成功,元组的第二项将返回一个
PublishResult
类型的数据,当前不包含任何字段。
接收消息
RTM 提供消息、状态、事件变更等信息的事件通知。通过设置事件监听,你可以接收已订阅频道中的消息和事件,示例代码如下:
rtm.addListener(
message: (event) {
print('Recieved a message from ${event.channelName}');
print('Message Type is ${event.messageType}');
print('Message : ${event.message}');
}
);
MessageEvent
中的 message
字段为 Uint8List
类型,当你收到字符串类型的消息后,可以使用 dart:convert
库中的 utf8.decode()
方法将其转换成 Srting
类型:
// convert Uint8List to String. ! means forced conversion
String message = utf8.decode(event.message!);
关于如何添加和设置事件监听,详见事件监听章节。