消息

  • Flutter

更新时间不可用

收发消息是 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。如果发送速率超限,将会有部分消息被丢弃。在满足要求的情况下,速率越低越好。

成功调用该方法后,订阅了该频道并开启了事件监听的其他用户会通过 message 收到这条消息,详见事件监听。

接口方法

你可以通过以下方式调用 publish 方法:

Dart
Future<(RtmStatus, PublishResult?)> publish(
    String channelName,
    String message,
    {
        RtmChannelType channelType = RtmChannelType.message,
        String? customType,
        bool storeInHistory = false
    }
);
参数类型必填默认值描述
channelNameString必填-
  • 如需向 Message Channel 发送消息,填写频道名称。
  • 如需向 User Channel 发送消息,填写用户 ID。
messageString必填-消息负载。
channelTypeRtmChannelType选填message频道类型。详见 RtmChannelType。
customTypeString选填-用户自定义字段。仅支持字符串型。
storeInHistorybool选填false

是否开启历史消息存储。开启后,消息在发送的同时会被存储到云端,便于用户在进入频道后可以查询到历史消息记录。

信息

历史消息功能目前处于 Public Beta 阶段。如需使用,需要前往控制台开通。

表格内容超出当前宽度,可横向滚动查看更多列。

接口方法

示例 1:向指定 Message Channel 发送 String 消息

Dart
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 消息

Dart
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 类型的数据,其中字段定义如下:
Dart
class RtmStatus {
    bool error;                   // 本次操作是否出错。
    String errorCode;             // 本次操作错误码。
    String operation;             // 本次操作的 API。
    String reason;                // 本次操作错误原因简述。
}

你可以通过检索 errorCode 字段的错误码了解错误原因,并找到对应的解决方法。

  • 如果该方法调用成功,元组的第二项将返回一个 PublishResult 类型的数据,当前不包含任何字段。

publishBinaryMessage

接口描述

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

信息

以下做法可有效提升消息收发的可靠性:

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

成功调用该方法后,SDK 会触发 message 事件通知。订阅了该频道并且开启了事件监听的用户将会收到该事件通知,详见事件监听。

接口方法

你可以通过以下方式调用 publishBinaryMessage 方法:

Dart
Future<PublishResult> publishBinaryMessage(
    String channelName,
    Uint8List message,
    {
        RtmChannelType channelType = RtmChannelType.message,
        String? customType,
        bool storeInHistory = false
    }
);
参数类型必填默认值描述
channelNameString必填-
  • 如需向 Message Channel 发送消息,填写频道名称。
  • 如需向 User Channel 发送消息,填写用户 ID。
messageUint8List必填-消息负载。
channelTypeRtmChannelType选填message频道类型。详见 RtmChannelType。
customTypeString选填-用户自定义字段。仅支持字符串型。
storeInHistorybool选填false

是否开启历史消息存储。开启后,消息在发送的同时会被存储到云端,便于用户在进入频道后可以查询到历史消息记录。

信息

历史消息功能目前处于 Public Beta 阶段。如需使用,需要前往控制台开通。

表格内容超出当前宽度,可横向滚动查看更多列。

接口方法

示例 1:向指定 Message Channel 发送 Binary 消息

Dart
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 消息

Dart
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 类型的数据,其中字段定义如下:
Dart
class RtmStatus {
    bool error;                   // 本次操作是否出错。
    String errorCode;             // 本次操作错误码。
    String operation;             // 本次操作的 API。
    String reason;                // 本次操作错误原因简述。
}

你可以通过检索 errorCode 字段的错误码了解错误原因,并找到对应的解决方法。

  • 如果该方法调用成功,元组的第二项将返回一个 PublishResult 类型的数据,当前不包含任何字段。

getMessages

接口描述

如果你需要从指定频道中获取历史消息,在客户端调用 getMessages 方法。

接口方法

你可以通过以下方式调用 getMessages 方法:

Dart
Future<(RtmStatus, GetMessagesResult?)> getMessages(
    String channelName, RtmChannelType channelType,
    {int messageCount = 100, int start = 0, int end = 0}
);
参数类型是否必填默认值描述
channelNameString必填-频道名称。
channelTypeRtmChannelType必填-频道类型。详见 RtmChannelType。
optionsGetHistoryMessagesOptions必填-查询选项。
表格内容超出当前宽度,可横向滚动查看更多列。

GetHistoryMessagesOptions 数据类型包含以下属性:

属性类型是否必填默认值描述
messageCountint选填100单次查询的最大消息数。如果单次查询的时间范围内消息数大于该值,则需多次调用 getMessages 方法进行查询。
startInt选填0历史消息开始的时间戳。
endInt选填0历史消息结束的时间戳。
表格内容超出当前宽度,可横向滚动查看更多列。

信息

RTM SDK 提供 start 和 end 参数,你可以根据实际需求进行设置:

  • start 和 end 为 UTC 时间戳,且两者间隔不能超过 24 小时(取 event 事件中返回的 timestamp 值)。
  • 如果你只设置了 start 参数,则你会获得比 start 时间戳更早的历史消息。
  • 如果你只设置了 end 参数,则你会获得当前时间戳到 end 时间戳(包含)之间的历史消息。
  • 如果你同时设置了 start 和 end 参数,则你会获得 start 和 end 时间戳(包含)之间的历史消息。

GetMessagesResult 数据类型包含以下属性:

属性类型描述
messageListList<HistoryMessage>历史消息列表。
countint获取的历史消息数。
newStartint下一条历史消息的发送时间戳。如果该参数为 0,则表示没有下一条历史消息。
表格内容超出当前宽度,可横向滚动查看更多列。

HistoryMessage 数据类型包含以下属性:

属性类型描述
messageTypeString消息类型,详见 RtmMessageType。
publisherString消息发布者 ID。
messageUint8List消息内容。
messageLengthInt消息长度。
customTypeString用户自定义字段。仅支持 String 型。
timestampInt消息发送的时间戳。
表格内容超出当前宽度,可横向滚动查看更多列。

基本用法

Dart
final history = rtmClient.getHistory();
final (_, result) = await history.getMessages(
  'chat_room',
  'MESSAGE',
  messageCount: 100,
  start: 0,
  end: 0,
);

接收消息

RTM 提供消息、状态、事件变更等信息的事件通知。通过设置事件监听,你可以接收已订阅频道中的消息和事件,示例代码如下:

Dart
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 类型:

Dart
// convert Uint8List to String. ! means forced conversion
String message = utf8.decode(event.message!);

关于如何添加和设置事件监听,详见事件监听章节。