消息

  • Web

更新时间不可用

收发消息是 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 传递。本地用户可以调用 publishTopicMessage 方法在 Topic 中发送消息,远端用户可以调用 subscribeTopic 方法订阅 Topic 并接收消息。

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

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

publish

接口描述

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

信息

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

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

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

接口方法

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

JavaScript
rtm.publish(
    channelName: string,
    message: string | Uint8Array,
    options?: object
): Promise<PublishResponse>;
参数类型是否必填默认值描述
messagestring/Uint8Array必填-消息负载。支持任意 string 类型和 Uint8Array 类型。
channelNamestring必填-
  • 如需向 Message Channel 发送消息,填写频道名称。
  • 如需向 User Channel 发送消息,填写用户 ID。
optionsobject选填-消息选项。
表格内容超出当前宽度,可横向滚动查看更多列。

options 对象中包含以下属性:

属性类型是否必填默认值描述
customTypestring选填-用户自定义字段。仅支持 string 型。
channelTypestring选填-频道类型。支持的取值见频道类型。
storeInHistoryboolean选填false是否将消息存储在历史消息中。如果设置为 true,消息将会被存储在历史消息中,并可以通过 getMessages 方法获取。
表格内容超出当前宽度,可横向滚动查看更多列。

基本用法

示例 1:向指定 Message Channel 发送 string 消息,并存储在历史消息中

JavaScript
try {
    const result = await rtm.publish( "my_channel", "Hello world", { channelType: "MESSAGE", storeInHistory: true });
    console.log(result);
} catch (status) {
    console.log(status);
}

示例 2:向指定 Message Channel 发送 Uint8Array 消息,并存储在历史消息中

JavaScript
const str2ab = function(str) {
    var buf = new ArrayBuffer(str.length * 2); // 每个字符占用 2 个字节
    var bufView = new Uint16Array(buf);
    for (var i = 0, strLen = str.length; i < strLen; i++) {
        bufView[i] = str.charCodeAt(i);
    }
    return buf;
};
var Message=str2ab("hello world");
try {
    const result = await rtm.publish("my_channel", Message, { channelType: "MESSAGE", storeInHistory: true });
    console.log(result);
} catch (status) {
    console.log(status);
}

示例 3:向指定 User Channel 发送 string 消息

JavaScript
try {
    const result = await rtm.publish("user_b", "Hello world", { channelType: "USER" });
    console.log(result);
} catch (status) {
    console.log(status);
}

示例 4:向指定 User Channel 发送 Uint8Array 消息

JavaScript
const str2ab = function(str) {
    var buf = new ArrayBuffer(str.length * 2); // 每个字符占用 2 个字节
    var bufView = new Uint16Array(buf);
    for (var i = 0, strLen = str.length; i < strLen; i++) {
        bufView[i] = str.charCodeAt(i);
    }
    return buf;
};
var Message=str2ab("hello world");
try {
    const result = await rtm.publish("user_b", Message, { channelType: "USER" });
    console.log(result);
} catch (status) {
    console.log(status);
}

信息

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

返回值

如果方法调用成功,则返回一个 PublishResponse 类型数据:

JavaScript
type PublishResponse = {
    timestamp: number,              // 预留字段
    channelName : string            // 频道名称
}

如果方法调用失败,则返回一个 ErrorInfo 类型数据:

JavaScript
type ErrorInfo = {
    error: boolean;                     // 本次操作是否出错
    operation: string;                  // 本次操作的 API 名称
    errorCode: number;                  // 错误码
    reason: string;                     // 错误描述
}

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

getMessages

接口描述

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

接口方法

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

JavaScript
getMessages(
    channelName: string,
    channelType: HistoryChannelType,
    options?: GetHistoryMessageOptions
  ): Promise<GetMessagesResponse>;
参数类型是否必填默认值描述
channelNamestring必填-频道名称。
channelTypestring必填-频道类型。详见 HistoryChannelType。
optionsobject选填-查询选项。
表格内容超出当前宽度,可横向滚动查看更多列。

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

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

信息

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

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

基本用法

JavaScript
const options = { messageCount: 50, start: 0, end: 0 }
try {
    const result = await rtm.history.getMessages( "my_channel", "MESSAGE", options);
    console.log(result);
} catch (status) {
    console.log(status);
}

返回值

如果方法调用成功,则返回一个 GetMessagesResponse 类型数据:

JavaScript
export interface GetMessagesResponse extends BaseResponse {
  // 历史消息列表
  messageList: HistoryMessage[];
  // 历史消息总数
  count: number;
  // 下一条历史消息的时间戳。如果该参数为 0,则表示没有下一条历史消息。
  newStart: number;
}

如果方法调用失败,则返回一个 ErrorInfo 类型数据:

JavaScript
type ErrorInfo = {
    error: boolean;                     // 本次操作是否出错
    operation: string;                  // 本次操作的 API 名称
    errorCode: number;                  // 错误码
    reason: string;                     // 错误描述
}

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

接收消息

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

JavaScript
rtm.addEventListener("message", event => {
    const channelType = event.channelType;      // Which channel type it is, Should be "STREAM", "MESSAGE" or "USER" .
    const channelName = event.channelName;      // Which channel does this message come from
    const topic = event.topicName;              // Which Topic does this message come from, it is valid when the channelType is "STREAM".
    const messageType = event.messageType;      // Which message type it is, Should be "STRING" or "BINARY" .
    const customType = event.customType;        // User defined type
    const publisher = event.publisher;          // Message publisher
    const message = event.message;              // Message payload
    const timestamp = event.timestamp;          // Message timestamp
});

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