初始配置
RTM SDK API 参考介绍了实时消息相关 API 的接口描述、接口方法、异步回调、基本用法示例代码和返回值。
想要了解详细的初始配置步骤,可以查看:
RtmConfig
接口描述
RtmConfig 用于设置 RTM 初始化时配置其他额外属性,这些配置属性会在整个 RTM 客户端的生命周期中生效,影响 RTM 客户端的行为。
接口方法
你可以通过以下方式创建 RtmConfig 实例:
import { RtmConfig, RtmAreaCode, RtmProtocolType, RtmLogLevel } from '@shengwang/rtm-full';
const config: RtmConfig = {
appId: 'your_appid',
userId: 'your_userid',
areaCode: RtmAreaCode.CN | RtmAreaCode.AS,
protocolType: RtmProtocolType.TCP_UDP,
presenceTimeout: 300,
heartbeatInterval: 5,
useStringUserId: true,
ispPolicyEnabled: false,
};
| 属性 | 类型 | 是否必填 | 默认值 | 描述 |
|---|---|---|---|---|
appId | string | 必填 | - | 声网控制台创建项目时获得的 App ID。 |
userId | string | 必填 | - | 用户 ID,用于标识用户或设备。为区分各用户和设备,你需要确保 userId 全局唯一,并且在用户或设备的生命周期内保持不变。 |
areaCode | RtmAreaCode | 选填 | GLOBAL | 服务区域代码,你可以根据自己业务部署的区域进行选择,详见 RtmAreaCode。 |
protocolType | RtmProtocolType | 选填 | TCP_UDP | 消息传输协议类型。RTM 默认使用一路 TCP 和一路 UDP 协议进行传输,你可以根据需要修改协议类型。详见 RtmProtocolType。 |
presenceTimeout | number | 选填 | 300 | Presence 的超时时间。单位为秒,取值范围为 [5,300]。即 RTM 服务器在判定客户端超时后,延迟多久向其他用户发送 REMOTE_TIMEOUT 事件通知。如果客户端在该参数设置的时间内重新建立连接并返回频道,则 RTM 服务器不会向频道中其他人发送 REMOTE_TIMEOUT 事件通知,也不会删除该用户的临时用户数据。 |
heartbeatInterval | number | 选填 | 5 | SDK 心跳时间。单位为秒,取值范围为 [5,1800]。即客户端向 RTM 服务器发送心跳包的时间间隔。如果客户端在该参数设置的时间内没有向 RTM 服务器发送心跳包,则 RTM 服务器会判定客户端超时。 信息 该参数会影响 PCU 计数,从而影响计费。 |
reconnectTimeout | number | 选填 | 0 | SDK 连接超时时间。单位为秒,取值范围为 [15,3600]。默认值 该参数对初次登录 RTM 服务和断线重连均有效:
|
useStringUserId | boolean | 选填 | true | 是否使用字符串类型的用户 ID:
当同时使用声网 RTC 和 RTM 产品时,需要确保 |
multipath | boolean | 选填 | false | 是否开启多路径传输。从 2.2.0 版本引入,目前仅对 Stream Channel 生效。 |
ispPolicyEnabled | boolean | 选填 | false | 是否开启 ISP 域名策略限制。在 IoT 场景下,设备可能受限于互联网服务提供商 (ISP),你可以通过该字段设置 SDK 的连接模式,连接到已向运营商报备的域名或 IP 白名单中的服务器:
|
logConfig | RtmLogConfig | 选填 | - | 本地日志存储的大小、位置和日志等级等配置属性。 |
proxyConfig | RtmProxyConfig | 选填 | - | 当使用 RTM 的 Proxy 功能时,需要配置此参数。 |
encryptionConfig | RtmEncryptionConfig | 选填 | - | 当使用 RTM 端侧加密功能时,需要配置此项参数。 |
privateConfig | RtmPrivateConfig | 选填 | - | 当使用 RTM 的私有化部署功能时,需要配置此项参数。 |
RtmLogConfig
RtmLogConfig 实例用来设置和存储本地日志文件 agora.log。在调试阶段,通过日志保存和跟踪 App 运行状态,你可以极大的提升效率。如果遇到复杂问题并需要声网技术人员协助调查,你需要提供该日志信息。RtmLogConfig 包含以下属性:
| 属性 | 类型 | 是否必填 | 默认值 | 描述 |
|---|---|---|---|---|
filePath | string | 选填 | '' | 日志存储路径。HarmonyOS 推荐使用应用沙箱路径,例如:/data/app/el2/100/base/your_application/files/rtm_logs。 |
fileSizeInKB | number | 选填 | 1024 | 日志文件大小,单位为 KB,取值范围为 [128,20480]。
|
level | RtmLogLevel | 选填 | INFO | 日志信息的输出等级,详见 RtmLogLevel。 |
RtmProxyConfig
RtmProxyConfig 实例用来设置客户端 Proxy 服务代理等相关属性。在一些网络服务受限的环境下,你可能需要使用此功能。
你需要妥善保管好你的 Proxy 用户名和密码。RTM 不会以任何方式解析、存储、转发你的用户名和密码。此外,如果你在 App 运行过程中修改 Proxy 的设置,该设置要重启 RTM Client 后才能生效。
RtmProxyConfig 包含以下属性:
| 属性 | 类型 | 是否必填 | 默认值 | 描述 |
|---|---|---|---|---|
server | string | 必填 | - | Proxy 服务器域名或 IP 地址。 |
account | string | 必填 | - | Proxy 登录账号。 |
password | string | 必填 | - | Proxy 登录密码。 |
proxyType | RtmProxyType | 选填 | NONE | Proxy 协议类型。详见 RtmProxyType。 |
port | number | 选填 | 0 | Proxy 监听端口。 |
RtmEncryptionConfig
RtmEncryptionConfig 实例用来设置客户端加密所需要的属性。成功设置加密方式、加密密钥等属性后,用户发送的所有消息或者设置的所有状态都会在客户端自动加密和解密。
一旦设置了加密,所有用户必须使用相同的加密模式和密钥,否则数据无法互通。
RtmEncryptionConfig 包含以下属性:
| 属性 | 类型 | 是否必填 | 默认值 | 描述 |
|---|---|---|---|---|
encryptionMode | RtmEncryptionMode | 选填 | NONE | 加密方式。详见 RtmEncryptionMode。 |
encryptionKey | string | 选填 | '' | 用户自定义加密密钥,长度无限制。声网推荐使用 32 字节的密钥。 |
encryptionSalt | Uint8Array | 选填 | - | 用户自定义加密盐,长度为 32 字节。声网推荐你在服务端使用 OpenSSL 生成盐。 |
RtmPrivateConfig
RtmPrivateConfig 实例用来设置私有化部署所需要的属性。
RtmPrivateConfig 包含以下属性:
| 属性 | 类型 | 是否必填 | 默认值 | 描述 |
|---|---|---|---|---|
serviceType | RtmServiceType | 选填 | - | 服务类型。详见 RtmServiceType。 |
accessPointHosts | string[] | 选填 | - | 服务器的地址数组,数组中支持填写域名或 IP 地址。 |
基本用法
import {
RtmConfig,
RtmLogLevel,
RtmProxyType,
RtmEncryptionMode,
RtmServiceType
} from '@shengwang/rtm-full';
// Create configuration with all options
const config: RtmConfig = {
appId: 'your_appid',
userId: 'your_userid',
// Log configuration
logConfig: {
level: RtmLogLevel.INFO,
filePath: '/data/app/el2/100/base/your_application/files/rtm_logs',
fileSizeInKB: 10240
},
// Proxy configuration
proxyConfig: {
proxyType: RtmProxyType.HTTP,
server: 'your_server_address',
port: 8080,
account: 'your_account',
password: 'your_password'
},
// Encryption configuration
encryptionConfig: {
encryptionKey: 'your_encryption_key',
encryptionMode: RtmEncryptionMode.AES_256_GCM,
encryptionSalt: new Uint8Array([1, 2, 3, 4, 5, /* ... 32 bytes total */])
},
// Private deployment configuration
privateConfig: {
accessPointHosts: ['host1.example.com', 'host2.example.com'],
serviceType: RtmServiceType.MESSAGE | RtmServiceType.STREAM
}
};
RtmClient
接口描述
调用 RtmClient 构造函数创建并初始化 RTM Client 实例。
- 该方法需要在 RTM 的其他 API 之前调用。
- 为区分各用户和设备,你需要确保
userId全局唯一,并且在用户或设备的生命周期内保持不变。 - RTM Client 采用单例模式,多次创建会返回同一个实例。
接口方法
你可以通过以下方式创建实例:
constructor(config: RtmConfig)
| 参数 | 类型 | 是否必填 | 默认值 | 描述 |
|---|---|---|---|---|
config | RtmConfig | 必填 | - | 初始化 RTM Client 的配置参数。详见 RtmConfig。 |
基本用法
import { RtmClient, RtmConfig } from '@shengwang/rtm-full';
const config: RtmConfig = {
appId: 'your_appid',
userId: 'your_userid'
};
try {
const rtmClient = new RtmClient(config);
console.log('RTM Client created successfully');
} catch (error) {
console.error('Failed to create RTM client:', error);
}
返回值
- 方法调用成功:一个
RtmClient对象实例。 - 方法调用失败:抛出异常。
事件监听
接口描述
RTM 总共有 8 种事件通知类型,如下表所示:
| 事件类型 | 描述 |
|---|---|
presence | 接收用户所订阅的 Message Channel 及加入的 Stream Channel 中所有的 Presence 事件通知。详见 PresenceEvent。 |
topic | 接收用户所加入的 Stream Channel 中所有 Topic 变更事件通知。详见 TopicEvent。 |
storage | 接收用户所订阅的 Message Channel 及加入的 Stream Channel 中所有的 Channel Metadata 事件通知,及订阅用户的 User Metadata 事件通知。详见 StorageEvent。 |
lock | 接收用户所订阅的 Message Channel 及加入的 Stream Channel 中所有的 Lock 事件通知。详见 LockEvent。 |
linkState | 接收客户端网络连接状态变更的事件通知。详见 LinkStateEvent。 |
token | 接收客户端 Token 相关的事件通知。详见 TokenEvent。 |
添加监听
你可以通过以下方式来监听事件通知:
import { RtmClient, LinkStateEvent, MessageEvent, TokenEvent, PresenceEvent, StorageEvent, LockEvent, TopicEvent, RtmMessageType, RtmTokenEventType, RtmPresenceEventType } from '@shengwang/rtm-full';
// Listen to link state changes
rtmClient.addEventListener('linkState', (event: object) => {
const linkEvent = event as LinkStateEvent;
console.log('Link state changed:', linkEvent.currentState);
console.log('Previous state:', linkEvent.previousState);
console.log('Reason:', linkEvent.reasonCode);
});
// Listen to incoming messages
rtmClient.addEventListener('message', (event: object) => {
const msgEvent = event as MessageEvent;
console.log('Received message from:', msgEvent.publisher);
console.log('Channel:', msgEvent.channelName);
if (msgEvent.messageType === RtmMessageType.STRING) {
console.log('Text message:', msgEvent.message);
} else {
console.log('Binary message length:', (msgEvent.message as Uint8Array).length);
}
});
// Listen to token events
rtmClient.addEventListener('token', (event: object) => {
const tokenEvent = event as TokenEvent;
if (tokenEvent.eventType === RtmTokenEventType.WILL_EXPIRE) {
console.log('Token will expire, renewing...');
rtmClient.renewToken('new_token_string');
}
});
// Listen to presence events
rtmClient.addEventListener('presence', (event: object) => {
const presenceEvent = event as PresenceEvent;
console.log('Presence event:', presenceEvent.eventType);
console.log('Channel:', presenceEvent.channelName);
});
// Listen to storage events
rtmClient.addEventListener('storage', (event: object) => {
const storageEvent = event as StorageEvent;
console.log('Storage event:', storageEvent.eventType);
console.log('Target:', storageEvent.target);
});
// Listen to lock events
rtmClient.addEventListener('lock', (event: object) => {
const lockEvent = event as LockEvent;
console.log('Lock event:', lockEvent.eventType);
console.log('Channel:', lockEvent.channelName);
});
// Listen to topic events
rtmClient.addEventListener('topic', (event: object) => {
const topicEvent = event as TopicEvent;
console.log('Topic event:', topicEvent.eventType);
console.log('Channel:', topicEvent.channelName);
});
删除监听
当你不再需要接收某个事件通知时,可以通过 removeEventListener 方法删除对应的监听器。
removeEventListener(eventName: string, callback?: (event: object) => void): void
| 参数 | 类型 | 是否必填 | 描述 |
|---|---|---|---|
eventName | string | 必填 | 事件名称,如 'linkState'、'message'、'token' 等 |
callback | (event: object) => void | 选填 | 要删除的回调函数。如果不提供,则删除该事件的所有监听器 |
你可以通过以下方式删除事件监听:
import { RtmClient, MessageEvent } from '@shengwang/rtm-full';
// 定义一个回调函数
const messageHandler = (event: object) => {
const msgEvent = event as MessageEvent;
console.log('Received message:', msgEvent.message);
};
// 添加监听
rtmClient.addEventListener('message', messageHandler);
// 删除特定的监听器
rtmClient.removeEventListener('message', messageHandler);
// 或者删除该事件的所有监听器
rtmClient.removeEventListener('message');
// 删除其他事件的监听器
rtmClient.removeEventListener('linkState');
rtmClient.removeEventListener('presence');
rtmClient.removeEventListener('storage');
- 如果提供了
callback参数,只会删除与该回调函数完全匹配的监听器。 - 如果不提供
callback参数,会删除该事件名称下的所有监听器。 - 建议在组件销毁或不再需要监听时及时删除监听器,以避免内存泄漏。
MessageEvent
消息事件。
MessageEvent 包含以下属性:
| 属性 | 类型 | 描述 |
|---|---|---|
channelType | RtmChannelType | 频道类型。详见 RtmChannelType。 |
messageType | RtmMessageType | 消息类型。详见 RtmMessageType。 |
channelName | string | 频道名称。 |
channelTopic | string | Topic 名称。 |
message | string | Uint8Array | 消息内容。根据 messageType 的值,可能是字符串或二进制数据。 |
publisher | string | 消息发布者 ID。 |
customType | string | 用户自定义字段。仅支持 String 型。 |
timestamp | number | 事件发生的时间戳。 |
PresenceEvent
用户 Presence 事件。
PresenceEvent 包含以下属性:
| 属性 | 类型 | 描述 |
|---|---|---|
eventType | RtmPresenceEventType | Presence 事件类型。详见 RtmPresenceEventType。 |
channelType | RtmChannelType | 频道类型。详见 RtmChannelType。 |
channelName | string | 事件发生的频道名称。 |
publisher | string | 触发此事件的用户 ID。 |
stateChanged | StateItem[] | 状态变更的键值对数组。仅当 eventType 为 REMOTE_STATE_CHANGED 时有效。 |
interval | IntervalInfo | null | Interval 状态下,当前频道在上一个周期内用户加入、离开、超时、状态变更等事件通知的聚合增量信息。仅当 eventType 为 INTERVAL 时非空。 |
snapshot | UserState[] | null | 当前频道的内所有用户及其状态的快照数据。仅当 eventType 为 SNAPSHOT 时非空。 |
timestamp | number | 事件发生的时间戳。 |
IntervalInfo 数据类型包含以下属性:
| 属性 | 类型 | 描述 |
|---|---|---|
join | string[] | 在上一个周期内加入频道的用户 ID 列表。 |
leave | string[] | 在上一个周期内离开频道的用户 ID 列表。 |
timeout | string[] | 在上一个周期内加入频道超时的用户 ID 列表。 |
userStateList | UserState[] | 在上一个周期内状态变更的用户列表。包含用户 ID 和状态键值对。 |
UserState 数据类型包含以下属性:
| 属性 | 类型 | 描述 |
|---|---|---|
userId | string | 用户 ID。 |
states | StateItem[] | 用户的临时状态信息列表。 |
StateItem 数据类型包含以下属性:
| 属性 | 类型 | 描述 |
|---|---|---|
key | string | 用户状态的键。如果指定的键已经存在,则该键的值会被新值覆盖;如果指定的键不存在,则 SDK 会新增该键/值对。 |
value | string | 用户状态的值。 |
TopicEvent
Topic 事件。
TopicEvent 包含以下属性:
| 属性 | 类型 | 描述 |
|---|---|---|
eventType | RtmTopicEventType | Topic 事件类型。详见 RtmTopicEventType。 |
channelName | string | 事件发生的频道名称。 |
publisher | string | 触发此事件的用户 ID。 |
topicInfos | TopicInfo[] | Topic 的详细信息,包含 Topic 名称、Topic 发布者等信息。 |
timestamp | number | 事件发生的时间戳。 |
TopicInfo 数据类型包含以下属性:
| 属性 | 类型 | 描述 |
|---|---|---|
topic | string | Topic 名称。 |
publishers | PublisherInfo[] | 消息发布者数组。 |
PublisherInfo 数据类型包含以下属性:
| 属性 | 类型 | 描述 |
|---|---|---|
publisherUserId | string | 消息发布者的用户 ID。 |
publisherMeta | string | 消息发布者的元数据。 |
StorageEvent
Storage 事件。
StorageEvent 包含以下属性:
| 属性 | 类型 | 描述 |
|---|---|---|
channelType | RtmChannelType | 频道类型。详见 RtmChannelType。 |
storageType | RtmStorageType | Storage 类型。详见 RtmStorageType。 |
eventType | RtmStorageEventType | Storage 事件类型。详见 RtmStorageEventType。 |
target | string | 用户 ID 或频道名称。 |
data | Metadata | Metadata Item。详见 Metadata。 |
timestamp | number | 事件发生的时间戳。 |
LockEvent
Lock 事件。
LockEvent 包含以下属性:
| 属性 | 类型 | 描述 |
|---|---|---|
channelType | RtmChannelType | 频道类型。详见 RtmChannelType。 |
eventType | RtmLockEventType | Lock 事件类型。详见 RtmLockEventType。 |
channelName | string | 频道名称。 |
lockDetails | LockDetail[] | Lock 的详情。 |
timestamp | number | 事件发生的时间戳。 |
LockDetail 数据类型包含以下属性:
| 属性 | 类型 | 描述 |
|---|---|---|
lockName | string | Lock 的名称。 |
owner | string | 拥有锁的用户 ID。 |
ttl | number | 锁的过期时间。单位为秒,取值范围为 [10,300]。当使用这把锁的用户掉线时,如果用户在过期时间之内重新回到频道,则该用户依旧可以使用锁;否则,该用户的锁会被释放,监听了 lock 事件通知的用户会收到 LOCK_RELEASED 事件。 |
LinkStateEvent
SDK 连接状态事件。
LinkStateEvent 包含以下属性:
| 属性 | 类型 | 描述 |
|---|---|---|
currentState | RtmLinkState | 当前的连接状态。详见 RtmLinkState。 |
previousState | RtmLinkState | 之前的连接状态。详见 RtmLinkState。 |
serviceType | RtmServiceType | 网络连接类型。详见 RtmServiceType。 |
operation | RtmLinkOperation | 触发本次状态迁移的操作。详见 RtmLinkOperation。 |
reasonCode | RtmLinkStateChangeReason | 本次状态迁移的原因。详见 RtmLinkStateChangeReason。 |
reason | string | 本次状态迁移的原因描述。 |
affectedChannels | string[] | 本次状态迁移影响的频道。 |
unrestoredChannels | UnrestoredChannelInfo[] | 未恢复订阅或加入的频道信息,包含频道名、频道类型和频道中的临时状态数据。一般情况下为空。 |
isResumed | boolean | 在连接断开的 2 分钟内,是否从 RTM_LINK_STATE_DISCONNECTED 状态恢复成 RTM_LINK_STATE_CONNECTED 状态。true 表示已恢复。 |
timestamp | number | 本次事件通知发送的时间戳。 |
TokenEvent
Token 事件。
TokenEvent 包含以下属性:
| 属性 | 类型 | 描述 |
|---|---|---|
eventType | RtmTokenEventType | Token 事件类型。详见 RtmTokenEventType。 |
reason | string | Token 事件的详细描述,提供事件触发原因的可读说明。 |
affectedResources | AffectedResources | 受此 Token 事件影响的资源,包含受影响的频道列表等信息。 |
timestamp | number | 事件发生的时间戳。 |
AffectedResources 数据类型包含以下属性:
| 属性 | 类型 | 描述 |
|---|---|---|
messageChannels | string[] | 受事件影响的 Message Channel 名称列表。 |
login
接口描述
创建并初始化 RTM 实例之后,你需要执行 login 操作以登录 RTM 服务。登录成功将使客户端与 RTM 服务器建立起长连接,之后客户端才能正常访问 RTM 资源。
用户成功登录 RTM 服务后,应用的 PCU 会增加,这将影响你的账单数据。
接口方法
你可以通过以下方法登录 RTM 系统:
async login(token?: string): Promise<LoginResponse>
| 参数 | 类型 | 是否必填 | 默认值 | 描述 |
|---|---|---|---|---|
token | string | 选填 | "" | 登录 RTM 系统的 Token。
|
返回值
该方法返回一个 Promise:
- Promise resolve:返回
LoginResponse对象。 - Promise reject:抛出
RtmError异常,包含错误码和错误原因。详见错误排查。
LoginResponse 数据结构如下:
| 属性 | 类型 | 描述 |
|---|---|---|
timestamp | number | 操作的时间戳(保留字段,供未来使用)。 |
基本用法
import { RtmClient, RtmError } from '@shengwang/rtm-full';
try {
const response = await rtmClient.login('your_token');
console.log('Login successful, timestamp:', response.timestamp);
} catch (error) {
if (error instanceof RtmError) {
console.error('Login failed:', error.errorCode, error.reason);
}
}
// Login with empty token (if token authentication is not enabled)
try {
const response = await rtmClient.login();
console.log('Login successful');
} catch (error) {
if (error instanceof RtmError) {
console.error('Login failed:', error.errorCode, error.reason);
}
}
logout
接口描述
当你不再需要操作后,可以登出系统。本操作会影响你账单中的 PCU 计费项。
接口方法
你可以通过以下接口退出登录:
async logout(): Promise<LogoutResponse>
返回值
该方法返回一个 Promise:
- Promise resolve:返回
LogoutResponse对象。 - Promise reject:抛出
RtmError异常,包含错误码和错误原因。详见错误排查。
LogoutResponse 数据结构如下:
| 属性 | 类型 | 描述 |
|---|---|---|
timestamp | number | 操作的时间戳(保留字段,供未来使用)。 |
基本用法
import { RtmError } from '@shengwang/rtm-full';
try {
const response = await rtmClient.logout();
console.log('Logout successful, timestamp:', response.timestamp);
} catch (error) {
if (error instanceof RtmError) {
console.error('Logout failed:', error.errorCode, error.reason);
}
}
release
接口描述
一旦不再需要 RTM 服务,推荐销毁 RtmClient 实例。这样做将使你免受内存泄漏甚至错误和异常引起的性能下降的影响。
release 是同步方法,调用后会立即清理资源。请确保不要在回调线程里,执行该方法。
接口方法
你可以通过以下方法销毁 RtmClient 实例:
release(): void
基本用法
// Release the RTM client instance
rtmClient.release();
console.log('RTM client released');
// After release, you need to create a new instance to use RTM again
返回值
无返回值。该方法是同步的,调用后立即生效。