# 初始配置 (/zh-CN/api-reference/rtm/harmonyos/configuration)

> For AI agents: see the complete documentation index at [llms.txt](/llms.txt).

RTM SDK API 参考介绍了实时消息相关 API 的接口描述、接口方法、异步回调、基本用法示例代码和返回值。

想要了解详细的初始配置步骤，可以查看：

- [应用配置](/zh-CN/realtime-media/rtm/build/rtm-initialization/application-setup)

## RtmConfig [#rtmconfig]

### 接口描述 [#接口描述]

`RtmConfig` 用于设置 RTM 初始化时配置其他额外属性，这些配置属性会在整个 RTM 客户端的生命周期中生效，影响 RTM 客户端的行为。

### 接口方法 [#接口方法]

你可以通过以下方式创建 `RtmConfig` 实例：

```typescript
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`](/zh-CN/api-reference/rtm/harmonyos/enumv#areacode)。 |
| `protocolType` | `RtmProtocolType` | 选填 | `TCP_UDP` | 消息传输协议类型。RTM 默认使用一路 TCP 和一路 UDP 协议进行传输，你可以根据需要修改协议类型。详见 [`RtmProtocolType`](/zh-CN/api-reference/rtm/harmonyos/enumv#protocoltype)。 |
| `presenceTimeout` | number | 选填 | `300` | Presence 的超时时间。单位为秒，取值范围为 [5,300]。即 RTM 服务器在判定客户端超时后，延迟多久向其他用户发送 `REMOTE_TIMEOUT` 事件通知。如果客户端在该参数设置的时间内重新建立连接并返回频道，则 RTM 服务器不会向频道中其他人发送 `REMOTE_TIMEOUT` 事件通知，也不会删除该用户的临时用户数据。 |
| `heartbeatInterval` | number | 选填 | `5` | [configuration-harmonyos-html-0-6-4 details](#table-slot-configuration-harmonyos-html-0-6-4) |
| `reconnectTimeout` | number | 选填 | `0` | [configuration-harmonyos-html-0-7-4 details](#table-slot-configuration-harmonyos-html-0-7-4) |
| `useStringUserId` | boolean | 选填 | `true` | [configuration-harmonyos-html-0-8-4 details](#table-slot-configuration-harmonyos-html-0-8-4) |
| `multipath` | boolean | 选填 | `false` | 是否开启多路径传输。从 2.2.0 版本引入，目前仅对 Stream Channel 生效。 |
| `ispPolicyEnabled` | boolean | 选填 | `false` | [configuration-harmonyos-html-0-10-4 details](#table-slot-configuration-harmonyos-html-0-10-4) |
| `logConfig` | `RtmLogConfig` | 选填 | - | 本地日志存储的大小、位置和日志等级等配置属性。 |
| `proxyConfig` | `RtmProxyConfig` | 选填 | - | 当使用 RTM 的 Proxy 功能时，需要配置此参数。 |
| `encryptionConfig` | `RtmEncryptionConfig` | 选填 | - | 当使用 RTM 端侧加密功能时，需要配置此项参数。 |
| `privateConfig` | `RtmPrivateConfig` | 选填 | - | 当使用 RTM 的私有化部署功能时，需要配置此项参数。 |

<a id="table-slot-configuration-harmonyos-html-0-6-4"></a>

**configuration-harmonyos-html-0-6-4 details**

SDK 心跳时间。单位为秒，取值范围为 [5,1800]。即客户端向 RTM 服务器发送心跳包的时间间隔。如果客户端在该参数设置的时间内没有向 RTM 服务器发送心跳包，则 RTM 服务器会判定客户端超时。

:::info[信息]
该参数会影响 PCU 计数，从而影响计费。
:::

<a id="table-slot-configuration-harmonyos-html-0-7-4"></a>

**configuration-harmonyos-html-0-7-4 details**

SDK 连接超时时间。单位为秒，取值范围为 [15,3600]。默认值 `0` 表示从不超时，SDK 会一直尝试重连，直到成功。

该参数对初次登录 RTM 服务和断线重连均有效：

- 如果初次登录超时，SDK 会触发 `login` 方法返回的 Promise reject，错误码为 `RTM_ERROR_LOGIN_TIMEOUT`；同时触发 `onLinkStateChanged` 事件，其中 `currentState` 为 `RTM_LINK_STATE_FAILED`，`reasonCode` 为 `RTM_LINK_CHANGE_REASON_LOGIN_TIMEOUT`；
- 如果断线重连超时，SDK 会触发 `onLinkStateChanged` 事件，其中 `currentState` 为 `RTM_LINK_STATE_FAILED`，`reasonCode` 为 `RTM_LINK_CHANGE_REASON_RECONNECT_TIMEOUT`。

<a id="table-slot-configuration-harmonyos-html-0-8-4"></a>

**configuration-harmonyos-html-0-8-4 details**

是否使用字符串类型的用户 ID：

- `true`: 使用 String 类型的用户 ID。
- `false`: 使用 Uint 类型的用户 ID，SDK 会自动将字符串类型的 `userId` 属性转换为 `Uint` 类型。该设置下，你需要在 `userId` 属性中传入内容为数值的字符串（例如 `"1234567"`），否则方法会调用失败。

当同时使用声网 RTC 和 RTM 产品时，需要确保 `userId` 一致。

<a id="table-slot-configuration-harmonyos-html-0-10-4"></a>

**configuration-harmonyos-html-0-10-4 details**

是否开启 ISP 域名策略限制。在 IoT 场景下，设备可能受限于互联网服务提供商 (ISP)，你可以通过该字段设置 SDK 的连接模式，连接到已向运营商报备的域名或 IP 白名单中的服务器：

- `true`: 开启 ISP 域名策略限制。该设置适用于 IoT 设备使用物联网卡进行网络访问的场景。SDK 会仅连接到已向运营商报备的域名或 IP 白名单中的服务器。
- `false`: （默认）关闭 ISP 域名策略限制。该设置适用于大部分普通场景。

#### RtmLogConfig [#rtmlogconfig]

`RtmLogConfig` 实例用来设置和存储本地日志文件 `agora.log`。在调试阶段，通过日志保存和跟踪 App 运行状态，你可以极大的提升效率。如果遇到复杂问题并需要声网技术人员协助调查，你需要提供该日志信息。`RtmLogConfig` 包含以下属性：

| 属性 | 类型 | 是否必填 | 默认值 | 描述 |
| --- | --- | --- | --- | --- |
| `filePath` | string | 选填 | `''` | 日志存储路径。HarmonyOS 推荐使用应用沙箱路径，例如：`/data/app/el2/100/base/your_application/files/rtm_logs`。 |
| `fileSizeInKB` | number | 选填 | `1024` | [configuration-harmonyos-html-1-2-4 details](#table-slot-configuration-harmonyos-html-1-2-4) |
| `level` | `RtmLogLevel` | 选填 | `INFO` | 日志信息的输出等级，详见 [`RtmLogLevel`](/zh-CN/api-reference/rtm/harmonyos/enumv#loglevel)。 |

<a id="table-slot-configuration-harmonyos-html-1-2-4"></a>

**configuration-harmonyos-html-1-2-4 details**

日志文件大小，单位为 KB，取值范围为 [128,20480]。

- 如果你填入的值小于 128，则 SDK 按照 128 设置。
- 如果你填入的值大于 20480，则 SDK 按照 20480 设置。

#### RtmProxyConfig [#rtmproxyconfig]

`RtmProxyConfig` 实例用来设置客户端 Proxy 服务代理等相关属性。在一些网络服务受限的环境下，你可能需要使用此功能。

:::info[信息]
你需要妥善保管好你的 Proxy 用户名和密码。RTM 不会以任何方式解析、存储、转发你的用户名和密码。此外，如果你在 App 运行过程中修改 Proxy 的设置，该设置要重启 RTM Client 后才能生效。
:::

`RtmProxyConfig` 包含以下属性：

| 属性  | 类型             |  是否必填  |  默认值  | 描述  |
|-----------|----------------|--------|-------| ----------- |
| `server`    | string           |  必填  | -             | Proxy 服务器域名或 IP 地址。                |
| `account`   | string           |  必填  | -            | Proxy 登录账号。   |
| `password`  | string           |  必填  | -            | Proxy 登录密码。   |
| `proxyType` | `RtmProxyType` |  选填  | `NONE` | Proxy 协议类型。详见 [`RtmProxyType`](/zh-CN/api-reference/rtm/harmonyos/enumv#proxytype)。 |
| `port`      | number              |  选填  | `0`             | Proxy 监听端口。   |

#### RtmEncryptionConfig [#rtmencryptionconfig]

`RtmEncryptionConfig` 实例用来设置客户端加密所需要的属性。成功设置加密方式、加密密钥等属性后，用户发送的所有消息或者设置的所有状态都会在客户端自动加密和解密。

:::info[信息]
一旦设置了加密，所有用户必须使用相同的加密模式和密钥，否则数据无法互通。
:::

`RtmEncryptionConfig` 包含以下属性：

| 属性 | 类型 | 是否必填 | 默认值 | 描述 |
| --- | --- | --- | --- | --- |
| `encryptionMode` | `RtmEncryptionMode` | 选填 | `NONE` | 加密方式。详见 [`RtmEncryptionMode`](/zh-CN/api-reference/rtm/harmonyos/enumv#encryptionmode)。 |
| `encryptionKey` | string | 选填 | `''` | 用户自定义加密密钥，长度无限制。声网推荐使用 32 字节的密钥。 |
| `encryptionSalt` | Uint8Array | 选填 | - | 用户自定义加密盐，长度为 32 字节。声网推荐你在服务端使用 OpenSSL 生成盐。 |

#### RtmPrivateConfig [#rtmprivateconfig]

`RtmPrivateConfig` 实例用来设置私有化部署所需要的属性。

`RtmPrivateConfig` 包含以下属性：

| 属性          | 类型                  |  是否必填  |  默认值  | 描述                      |
|-----|-------|--------|------------| ---------------- |
| `serviceType`    | `RtmServiceType` |  选填  | - | 服务类型。详见 [`RtmServiceType`](/zh-CN/api-reference/rtm/harmonyos/enumv#rtmservicetype)。 |
| `accessPointHosts`    | string[] |  选填  | - | 服务器的地址数组，数组中支持填写域名或 IP 地址。 |

### 基本用法 [#基本用法]

```typescript
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
  }
};
```

<a id="Init"></a>

## RtmClient [#rtmclient]

### 接口描述 [#接口描述-1]

调用 `RtmClient` 构造函数创建并初始化 RTM Client 实例。

:::info[信息]
- 该方法需要在 RTM 的其他 API 之前调用。
- 为区分各用户和设备，你需要确保 `userId` 全局唯一，并且在用户或设备的生命周期内保持不变。
:::

### 接口方法 [#接口方法-1]

你可以通过以下方式创建实例：

```typescript
constructor(config: RtmConfig)
```

|   参数   |  类型  | 是否必填 | 默认值 | 描述          |
| ------ | --------- | ------ | ---- | -------------- |
| `config` | `RtmConfig` |   必填   |   -    | 初始化 RTM Client 的配置参数。详见 `RtmConfig`。 |

### 基本用法 [#基本用法-1]

```typescript
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` 对象实例。
- 方法调用失败：抛出异常。

## 事件监听 [#事件监听]

### 接口描述 [#接口描述-2]

RTM 总共有 8 种事件通知类型，如下表所示：

| 事件类型 | 描述 |
| --- | --- |
| <code className="index-group-item-rtmeventlistener index-api-onmessageevent" id="message">message</code> | <span className="index-desc-onmessageevent">接收用户所订阅的 Message Channel 及 Topic 中的所有消息事件通知。详见 [`MessageEvent`](#messageevent)。</span> |
| <code className="index-group-item-rtmeventlistener index-api-onpresenceevent" id="presence">presence</code> | <span className="index-desc-onpresenceevent">接收用户所订阅的 Message Channel 及加入的 Stream Channel 中所有的 Presence 事件通知。详见 [`PresenceEvent`](#presenceevent)。</span> |
| <code className="index-group-item-rtmeventlistener index-api-ontopicevent" id="topic">topic</code> | <span className="index-desc-ontopicevent">接收用户所加入的 Stream Channel 中所有 Topic 变更事件通知。详见 [`TopicEvent`](#topicevent)。</span> |
| <code className="index-group-item-rtmeventlistener index-api-onstorageevent" id="storage">storage</code> | <span className="index-desc-onstorageevent">接收用户所订阅的 Message Channel 及加入的 Stream Channel 中所有的 Channel Metadata 事件通知，及订阅用户的 User Metadata 事件通知。详见 [`StorageEvent`](#storageevent)。</span> |
| <code className="index-group-item-rtmeventlistener index-api-onlockevent" id="lock">lock</code> | <span className="index-desc-onlockevent">接收用户所订阅的 Message Channel 及加入的 Stream Channel 中所有的 Lock 事件通知。详见 [`LockEvent`](#lockevent)。</span> |
| <code className="index-group-item-rtmeventlistener index-api-onlinkstateevent" id="linkState">linkState</code> | <span className="index-desc-onlinkstateevent">接收客户端网络连接状态变更的事件通知。详见 [`LinkStateEvent`](#linkstateevent)。</span> |
| <code className="index-group-item-rtmeventlistener index-api-ontokenevent" id="token">token</code> | <span className="index-desc-ontokenwillexpire">接收客户端 Token 相关的事件通知。详见 [`TokenEvent`](#tokenevent)。</span> |

### 添加监听 [#添加监听]

你可以通过以下方式来监听事件通知：

```typescript
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` 方法删除对应的监听器。

```typescript
removeEventListener(eventName: string, callback?: (event: object) => void): void
```

| 参数 | 类型 | 是否必填 | 描述 |
|------|------|----------|------|
| `eventName` | string | 必填 | 事件名称，如 `'linkState'`、`'message'`、`'token'` 等 |
| `callback` | `(event: object) => void` | 选填 | 要删除的回调函数。如果不提供，则删除该事件的所有监听器 |

你可以通过以下方式删除事件监听：

```typescript
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');
```

:::info[信息]
- 如果提供了 `callback` 参数，只会删除与该回调函数完全匹配的监听器。
- 如果不提供 `callback` 参数，会删除该事件名称下的所有监听器。
- 建议在组件销毁或不再需要监听时及时删除监听器，以避免内存泄漏。
:::

#### MessageEvent [#messageevent]

消息事件。

`MessageEvent` 包含以下属性：

| 属性        |  类型  |   描述     |
|----|-----| ----------------- |
| `channelType`            | `RtmChannelType`    |  频道类型。详见 [`RtmChannelType`](/zh-CN/api-reference/rtm/harmonyos/enumv#channeltype)。   |
| `messageType`            | `RtmMessageType`    |  消息类型。详见 [`RtmMessageType`](/zh-CN/api-reference/rtm/harmonyos/enumv#messagetype)。   |
| `channelName`            | string                |  频道名称。   |
| `channelTopic`           | string                |  Topic 名称。   |
| `message`                | string \| Uint8Array                |  消息内容。根据 `messageType` 的值，可能是字符串或二进制数据。   |
| `publisher`              | string                |  消息发布者 ID。   |
| `customType` | string | 用户自定义字段。仅支持 String 型。                |
| `timestamp` | number | 事件发生的时间戳。                |

#### PresenceEvent [#presenceevent]

用户 Presence 事件。

`PresenceEvent` 包含以下属性：

| 属性       |  类型  |   描述       |
|----|-----| ----------- |
| `eventType`            | `RtmPresenceEventType`    |   Presence 事件类型。详见 [`RtmPresenceEventType`](/zh-CN/api-reference/rtm/harmonyos/enumv#presencetype)。  |
| `channelType`            | `RtmChannelType`    |  频道类型。详见 [`RtmChannelType`](/zh-CN/api-reference/rtm/harmonyos/enumv#channeltype)。   |
| `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 和状态键值对。 |
| `totalOccupancy` | number | 当前频道的总在线人数。在大频道优化模式下，该值表示频道内所有在线用户的数量，不受最多同步 512 名用户明细的限制；但该值可能有短暂延迟。 |

`UserState` 数据类型包含以下属性：

|  属性  |  类型  | 描述      |
| ---- | ------ | -------- |
| `userId`         |  string  |  用户 ID。     |
| `states`         |    `StateItem[]`      | 用户的临时状态信息列表。        |

`StateItem` 数据类型包含以下属性：

|  属性  |  类型  | 描述                            |
| ------ | ------- | ------ |
| `key`         |         string        | 用户状态的键。如果指定的键已经存在，则该键的值会被新值覆盖；如果指定的键不存在，则 SDK 会新增该键/值对。     |
| `value` | string | 用户状态的值。 |

#### TopicEvent [#topicevent]

Topic 事件。

`TopicEvent` 包含以下属性：

| 属性        |  类型  |   描述   |
|----|-----| ------ |
| `eventType`            | `RtmTopicEventType`    |  Topic 事件类型。详见 [`RtmTopicEventType`](/zh-CN/api-reference/rtm/harmonyos/enumv#topictype)。  |
| `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 [#storageevent]

Storage 事件。

`StorageEvent` 包含以下属性：

| 属性         |  类型  |   描述      |
|----|-----| ------- |
| `channelType`            | `RtmChannelType`    |  频道类型。详见 [`RtmChannelType`](/zh-CN/api-reference/rtm/harmonyos/enumv#channeltype)。   |
| `storageType`            | `RtmStorageType`    |  Storage 类型。详见 [`RtmStorageType`](/zh-CN/api-reference/rtm/harmonyos/enumv#storagetype)。  |
| `eventType`            | `RtmStorageEventType`    |  Storage 事件类型。详见 [`RtmStorageEventType`](/zh-CN/api-reference/rtm/harmonyos/enumv#storageeventtype)。  |
| `target`              | string                |  用户 ID 或频道名称。   |
| `data`            | `Metadata`               |   Metadata Item。详见 [`Metadata`](/zh-CN/api-reference/rtm/harmonyos/storage#setchannelmetadata)。   |
| `timestamp` | number | 事件发生的时间戳。                |

#### LockEvent [#lockevent]

Lock 事件。

`LockEvent` 包含以下属性：

| 属性        |  类型  |   描述                |
|----|-----| ----- |
| `channelType`            | `RtmChannelType`    |  频道类型。详见 [`RtmChannelType`](/zh-CN/api-reference/rtm/harmonyos/enumv#channeltype)。   |
| `eventType`            | `RtmLockEventType`    |  Lock 事件类型。详见 [`RtmLockEventType`](/zh-CN/api-reference/rtm/harmonyos/enumv#locktype)。    |
| `channelName`              | string                |  频道名称。   |
| `lockDetails`            | `LockDetail[]`               |  Lock 的详情。   |
| `timestamp` | number | 事件发生的时间戳。                |

`LockDetail` 数据类型包含以下属性：

|  属性  |  类型  | 描述      |
| ---- | ------| --------- |
| `lockName`         |         string         | Lock 的名称。               |
| `owner`    | string  | 拥有锁的用户 ID。   |
| `ttl`    | number | 锁的过期时间。单位为秒，取值范围为 [10,300]。当使用这把锁的用户掉线时，如果用户在过期时间之内重新回到频道，则该用户依旧可以使用锁；否则，该用户的锁会被释放，监听了 `lock` 事件通知的用户会收到 `LOCK_RELEASED` 事件。      |

#### LinkStateEvent [#linkstateevent]

SDK 连接状态事件。

`LinkStateEvent` 包含以下属性：

| 属性        |  类型  |   描述            |
|----|-----| ------------- |
| `currentState`            | `RtmLinkState`    |  当前的连接状态。详见 [`RtmLinkState`](/zh-CN/api-reference/rtm/harmonyos/enumv#linkstate)。   |
| `previousState`            | `RtmLinkState`    |  之前的连接状态。详见 [`RtmLinkState`](/zh-CN/api-reference/rtm/harmonyos/enumv#linkstate)。   |
| `serviceType`    | `RtmServiceType` | 网络连接类型。详见 [`RtmServiceType`](/zh-CN/api-reference/rtm/harmonyos/enumv#rtmservicetype)。 |
| `operation`    | `RtmLinkOperation` | 触发本次状态迁移的操作。详见 [`RtmLinkOperation`](/zh-CN/api-reference/rtm/harmonyos/enumv#linkoperation)。 |
| `reasonCode`    | `RtmLinkStateChangeReason` | 本次状态迁移的原因。详见 [`RtmLinkStateChangeReason`](/zh-CN/api-reference/rtm/harmonyos/enumv#linkstatechangereason)。 |
| `reason`    | string | 本次状态迁移的原因描述。 |
| `affectedChannels`    | string[] | 本次状态迁移影响的频道。 |
| `unrestoredChannels`    | `UnrestoredChannelInfo[]` | 未恢复订阅或加入的频道信息，包含频道名、频道类型和频道中的临时状态数据。一般情况下为空。 |
| `isResumed`    | boolean | 在连接断开的 2 分钟内，是否从 `RTM_LINK_STATE_DISCONNECTED` 状态恢复成 `RTM_LINK_STATE_CONNECTED` 状态。`true` 表示已恢复。 |
| `timestamp`    | number | 本次事件通知发送的时间戳。 |

#### TokenEvent [#tokenevent]

Token 事件。

`TokenEvent` 包含以下属性：

| 属性        |  类型  |   描述            |
|----|-----| ------------- |
| `eventType`            | `RtmTokenEventType`    |  Token 事件类型。   |
| `reason`            | string    |  Token 事件的详细描述，提供事件触发原因的可读说明。   |
| `affectedResources`    | `AffectedResources` | 受此 Token 事件影响的资源，包含受影响的频道列表等信息。 |
| `timestamp`    | number | 事件发生的时间戳。 |

`AffectedResources` 数据类型包含以下属性：

|  属性  |  类型  | 描述      |
| ---- | ------| --------- |
| `messageChannels`         |         string[]         | 受事件影响的 Message Channel 名称列表。               |

## login [#login]

### 接口描述 [#接口描述-3]

创建并初始化 RTM 实例之后，你需要执行 `login` 操作以登录 RTM 服务。登录成功将使客户端与 RTM 服务器建立起长连接，之后客户端才能正常访问 RTM 资源。

:::info[信息]
用户成功登录 RTM 服务后，应用的 PCU 会增加，这将影响你的账单数据。
:::

### 接口方法 [#接口方法-2]

你可以通过以下方法登录 RTM 系统：

```typescript
async login(token?: string): Promise<LoginResponse>
```

| 参数 | 类型 | 是否必填 | 默认值 | 描述 |
| --- | --- | --- | --- | --- |
| `token` | string | 选填 | `""` | [configuration-harmonyos-html-4-1-4 details](#table-slot-configuration-harmonyos-html-4-1-4) |

<a id="table-slot-configuration-harmonyos-html-4-1-4"></a>

**configuration-harmonyos-html-4-1-4 details**

登录 RTM 系统的 Token。

- 如果你的项目开启了 Token 鉴权，你可以填入 [RTM 临时 Token](/zh-CN/realtime-media/rtm/build/rtm-initialization/enable-service#5-获取临时-token) 或 Token 服务器生成的 RTM 正式 Token。详见[客户端鉴权](/zh-CN/realtime-media/rtm/build/authentication-and-connection/user-authentication)和[部署 RTM Token 服务器](/zh-CN/realtime-media/rtm/build/authentication-and-connection/token-generation)。
- 如果你的项目未开启 Token 鉴权，你可以填入空字符串或开通了 RTM 服务的项目 App ID。

### 返回值 [#返回值-1]

该方法返回一个 Promise：

- Promise resolve：返回 `LoginResponse` 对象。
- Promise reject：抛出 `RtmError` 异常，包含错误码和错误原因。详见[错误排查](/zh-CN/realtime-media/rtm/build/troubleshooting)。

`LoginResponse` 数据结构如下：

| 属性 | 类型 | 描述 |
| --- | --- | --- |
| `timestamp` | number | 操作的时间戳（保留字段，供未来使用）。 |

### 基本用法 [#基本用法-2]

```typescript
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 [#logout]

### 接口描述 [#接口描述-4]

当你不再需要操作后，可以登出系统。本操作会影响你账单中的 PCU 计费项。

### 接口方法 [#接口方法-3]

你可以通过以下接口退出登录：

```typescript
async logout(): Promise<LogoutResponse>
```

### 返回值 [#返回值-2]

该方法返回一个 Promise：

- Promise resolve：返回 `LogoutResponse` 对象。
- Promise reject：抛出 `RtmError` 异常，包含错误码和错误原因。详见[错误排查](/zh-CN/realtime-media/rtm/build/troubleshooting)。

`LogoutResponse` 数据结构如下：

| 属性 | 类型 | 描述 |
| --- | --- | --- |
| `timestamp` | number | 操作的时间戳（保留字段，供未来使用）。 |

### 基本用法 [#基本用法-3]

```typescript
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 [#release]

### 接口描述 [#接口描述-5]

一旦不再需要 RTM 服务，推荐销毁 `RtmClient` 实例。这样做将使你免受内存泄漏甚至错误和异常引起的性能下降的影响。

:::info[信息]
`release` 是同步方法，调用后会立即清理资源。请确保不要在回调线程里，执行该方法。
:::

### 接口方法 [#接口方法-4]

你可以通过以下方法销毁 `RtmClient` 实例：

```typescript
release(): void
```

### 基本用法 [#基本用法-4]

```typescript
// 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
```

### 返回值 [#返回值-3]

无返回值。该方法是同步的，调用后立即生效。
