消息
收发消息是 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 方法:
async publish(channelName: string, message: string | Uint8Array, options: PublishOptions): Promise<PublishResponse>
| 参数 | 类型 | 是否必填 | 默认值 | 描述 |
|---|---|---|---|---|
channelName | string | 必填 | - |
|
message | string | Uint8Array | 必填 | - | 消息负载。可以是字符串或二进制数据。 |
options | PublishOptions | 必填 | - | 消息选项。 |
PublishOptions 数据类型包含以下属性:
| 属性 | 类型 | 是否必填 | 默认值 | 描述 |
|---|---|---|---|---|
channelType | RtmChannelType | 选填 | MESSAGE | 频道类型。详见 RtmChannelType。 |
customType | string | 选填 | '' | 用户自定义字段。仅支持字符串型。 |
storeInHistory | boolean | 选填 | false | 是否开启历史消息存储。开启后,消息在发送的同时会被存储到云端,便于用户在进入频道后可以查询到历史消息记录。 信息 历史消息功能目前处于 Public Beta 阶段。如需使用,需要前往控制台开通。 |
返回值
该方法返回一个 Promise,成功时 resolve 并返回 PublishResponse 对象,失败时 reject 并抛出 RtmError 异常。
PublishResponse 数据结构如下:
| 属性 | 类型 | 描述 |
|---|---|---|
timestamp | number | 操作的时间戳(保留字段,供未来使用)。 |
基本用法
示例 1:向指定 Message Channel 发送 String 消息
import { RtmClient, RtmError, RtmChannelType } from '@shengwang/rtm-full';
import type { PublishOptions } from '@shengwang/rtm-full';
const options: PublishOptions = {
channelType: RtmChannelType.MESSAGE,
customType: 'PlainText',
storeInHistory: true
};
try {
const response = await rtmClient.publish('channelName', 'hello world', options);
console.log('Message published successfully');
} catch (error) {
if (error instanceof RtmError) {
console.error('Publish message failed:', error.errorCode, error.reason);
}
}
示例 2:向指定频道 Message Channel 发送 Byte 消息
import { RtmClient, RtmError, RtmChannelType } from '@shengwang/rtm-full';
import type { PublishOptions } from '@shengwang/rtm-full';
const options: PublishOptions = {
channelType: RtmChannelType.MESSAGE,
customType: 'ByteArray',
storeInHistory: true
};
const message = new Uint8Array([0x00, 0x01, 0x02, 0x03, 0x04]);
try {
const response = await rtmClient.publish('channelName', message, options);
console.log('Binary message published successfully');
} catch (error) {
if (error instanceof RtmError) {
console.error('Publish message failed:', error.errorCode, error.reason);
}
}
示例 3:向指定 User Channel 发送 String 消息
import { RtmClient, RtmError, RtmChannelType } from '@shengwang/rtm-full';
import type { PublishOptions } from '@shengwang/rtm-full';
const options: PublishOptions = {
channelType: RtmChannelType.USER,
customType: 'PlainText',
storeInHistory: true
};
try {
const response = await rtmClient.publish('userId', 'hello world', options);
console.log('Message sent to user successfully');
} catch (error) {
if (error instanceof RtmError) {
console.error('Publish message failed:', error.errorCode, error.reason);
}
}
示例 4:向指定 User Channel 发送 Byte 消息
import { RtmClient, RtmError, RtmChannelType } from '@shengwang/rtm-full';
import type { PublishOptions } from '@shengwang/rtm-full';
const options: PublishOptions = {
channelType: RtmChannelType.USER,
customType: 'ByteArray',
storeInHistory: true
};
const message = new Uint8Array([0x00, 0x01, 0x02, 0x03, 0x04]);
try {
const response = await rtmClient.publish('userId', message, options);
console.log('Binary message sent to user successfully');
} catch (error) {
if (error instanceof RtmError) {
console.error('Publish message failed:', error.errorCode, error.reason);
}
}
getMessages
接口描述
如果你需要从指定频道中获取历史消息,在客户端调用 getMessages 方法。
接口方法
你可以通过以下方式调用 getMessages 方法:
async getMessages(channelName: string, channelType: RtmChannelType, options?: GetHistoryMessagesOptions): Promise<GetMessagesResponse>
| 参数 | 类型 | 是否必填 | 默认值 | 描述 |
|---|---|---|---|---|
channelName | string | 必填 | - | 频道名称。 |
channelType | RtmChannelType | 必填 | - | 频道类型。详见 RtmChannelType。 |
options | GetHistoryMessagesOptions | 选填 | {} | 查询选项。 |
GetHistoryMessagesOptions 数据类型包含以下属性:
| 属性 | 类型 | 是否必填 | 默认值 | 描述 |
|---|---|---|---|---|
messageCount | number | 选填 | 100 | 单次查询的最大消息数。如果单次查询的时间范围内消息数大于该值,则需多次调用 getMessages 方法进行查询。 |
start | number | 选填 | 0 | 历史消息开始的时间戳。 |
end | number | 选填 | 0 | 历史消息结束的时间戳。 |
RTM SDK 提供 start 和 end 参数,你可以根据实际需求进行设置:
start和end为 UTC 时间戳,且两者间隔不能超过 24 小时(取event事件中返回的timestamp值)。- 如果你只设置了
start参数,则你会获得比start时间戳更早的历史消息。 - 如果你只设置了
end参数,则你会获得当前时间戳到end时间戳(包含)之间的历史消息。 - 如果你同时设置了
start和end参数,则你会获得start和end时间戳(包含)之间的历史消息。
返回值
该方法返回一个 Promise,成功时 resolve 并返回 GetMessagesResponse 对象,失败时 reject 并抛出 RtmError 异常。
GetMessagesResponse 数据结构如下:
| 属性 | 类型 | 描述 |
|---|---|---|
timestamp | number | 操作的时间戳(保留字段,供未来使用)。 |
newStart | number | 下一条历史消息的发送时间戳。如果该参数为 0,则表示没有下一条历史消息。 |
messageList | HistoryMessage[] | 历史消息列表。 |
HistoryMessage 数据结构如下:
| 属性 | 类型 | 描述 |
|---|---|---|
message | string | Uint8Array | 消息内容。 |
messageType | RtmMessageType | 消息类型。 |
publisher | string | 消息发布者的用户 ID。 |
customType | string | 用户自定义字段。 |
timestamp | number | 消息被 RTM 服务器接收的时间戳(毫秒)。 |
基本用法
import { RtmClient, RtmError, RtmChannelType } from '@shengwang/rtm-full';
import type { GetHistoryMessagesOptions } from '@shengwang/rtm-full';
// Get history messages
const options: GetHistoryMessagesOptions = {
start: 0,
end: 0,
messageCount: 100
};
try {
const response = await rtmClient.history.getMessages('channelName', RtmChannelType.MESSAGE, options);
console.log('Get history messages success, new start:', response.newStart);
console.log('Retrieved', response.messageList.length, 'messages');
// Process messages
response.messageList.forEach((msg) => {
console.log(`${msg.publisher} at ${msg.timestamp}:`, msg.message);
});
// If there are more messages, fetch next batch
if (response.newStart !== 0) {
const nextBatch = await rtmClient.history.getMessages('channelName', RtmChannelType.MESSAGE, {
messageCount: 100,
start: response.newStart
});
console.log('Retrieved next batch:', nextBatch.messageList.length, 'messages');
}
} catch (error) {
if (error instanceof RtmError) {
console.error('Get history messages failed:', error.errorCode, error.reason);
}
}
接收消息
RTM 提供消息、状态、事件变更等信息的事件通知。通过设置事件监听,你可以接收已订阅频道中的消息和事件。以接收 User Channel 中的消息为例,示例代码如下:
import { RtmClient, RtmChannelType } from '@shengwang/rtm-full';
import type { RtmMessageEvent } from '@shengwang/rtm-full';
// Add event listener
rtmClient.addEventListener('message', (event: object) => {
const messageEvent = event as RtmMessageEvent;
// User Channel private message
if (messageEvent.channelType === RtmChannelType.USER) {
console.log('Received message from', messageEvent.publisher);
console.log('Message:', messageEvent.message);
console.log('Custom type:', messageEvent.customType);
}
});
关于如何添加和设置事件监听,详见事件监听章节。