# Lock (/zh-CN/api-reference/rtm/flutter/lock)

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

临界资源一次只能供一个进程使用，如果不同的进程之间共享了某个临界资源，则各进程需要采取互斥的方式来防止彼此干扰。RTM 提供一整套 Lock 的方案，通过控制分布式系统的不同进程，你可以解决用户在访问共享资源时的竞争问题。

:::info[信息]
客户端 SDK 具备设置、删除、撤销锁的能力，我们建议你根据实际业务需求控制端侧对锁的操作权限。
:::

## setLock [#setlock]

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

你需要配置锁的名称、过期时间 TTL 等属性，然后调用 `setLock` 方法进行配置。配置成功后，频道中的所有用户会收到 `lockSet` 类型的 `lock` 事件通知，详见[事件监听](/zh-CN/api-reference/rtm/flutter/configuration#事件监听)。

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

你可以通过以下方式调用 `setLock` 方法：

```dart
Future<(RtmStatus, SetLockResult?)> setLock(
    String channelName,
    RtmChannelType channelType,
    String lockName,
    {
        int? ttl = 10
    }
);
```

| 参数 | 类型 | 必填 | 默认值 | 描述 |
| --- | --- | --- | --- | --- |
| `channelName` | String | 必填 | - | 频道名称。 |
| `channelType` | `RtmChannelType` | 必填 | - | 频道类型。详见 [`RtmChannelType`](/zh-CN/api-reference/rtm/flutter/enumv#channeltype)。 |
| `lockName` | String | 必填 | - | 锁的名称。 |
| `ttl` | int | 选填 | 10 | 设置锁的过期时间。单位为秒，取值范围为 [10,300]。当使用这把锁的用户掉线时，如果用户在过期时间之内重新回到频道，则该用户依旧可以使用锁；否则，该用户的锁会被释放，监听了 `lock` 事件通知的用户会收到 `lockReleased` 事件。 |

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

```dart
var (status,response) =
    await rtmClient.getLock.setLock( "myChannel", RtmChannelType.message, "myLock", ttl:15);

if (status.error == true) {
    print(status);
} else {
    print(response);
}
```

### 返回值 [#返回值]

调用此方法，会返回 `Future<(RtmStatus,  SetLockResult?)>` 类型的元组数据。

- 无论该方法是否调用成功，元组的第一项都会返回一个 `RtmStatus` 类型的数据，其中字段定义如下：

```dart
class RtmStatus {
    bool error;                   // 本次操作是否出错。
    String errorCode;             // 本次操作错误码。
    String operation;             // 本次操作的 API。
    String reason;                // 本次操作错误原因简述。
}
```

你可以通过检索 `errorCode` 字段的[错误码](/zh-CN/realtime-media/rtm/build/troubleshooting)了解错误原因，并找到对应的解决方法。

- 如果该方法调用成功，元组的第二项将返回一个 ` SetLockResult` 类型的数据，定义如下：

  ```dart
  class SetLockResult {
      final String channelName;                           // 频道名称
      final RtmChannelType channelType;                   // 频道类型
      final String lockName;                              // 锁的名称
  }
  ```

## acquireLock [#acquirelock]

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

成功配置 Lock 后，你可以在客户端调用 `acquireLock` 方法获取锁的使用权。成功获取锁后，频道中的其他用户会收到 `lockAcquired` 类型的 `lock` 事件通知，详见[事件监听](/zh-CN/api-reference/rtm/flutter/configuration#事件监听)。

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

你可以通过以下方式调用 `acquireLock` 方法：

```dart
Future<(RtmStatus, AcquireLockResult?)> acquireLock(
    String channelName,
    RtmChannelType channelType,
    String lockName,
    {
        bool retry = false
    }
);
```

| 参数 | 类型 | 必填 | 默认值 | 描述 |
| --- | --- | --- | --- | --- |
| `channelName` | String | 必填 | - | 频道名称。 |
| `channelType` | `RtmChannelType` | 必填 | - | 频道类型。详见 [`RtmChannelType`](/zh-CN/api-reference/rtm/flutter/enumv#channeltype)。 |
| `lockName` | String | 必填 | - | 锁的名称。 |
| `retry` | bool | 选填 | false | 设置在获取锁失败后是否继续尝试，直到成功获取或退出频道为止。 |

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

```dart
var (status,response) =
    await rtmClient.getLock.acquireLock("myChannel", RtmChannelType.message, "myLock", retry:true);

if (status.error == true) {
    print(status);
} else {
    print(response);
}
```

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

调用此方法，会返回 `Future<(RtmStatus,  AcquireLockResult?)>` 类型的元组数据。

- 无论该方法是否调用成功，元组的第一项都会返回一个 `RtmStatus` 类型的数据，其中字段定义如下：

```dart
class RtmStatus {
    bool error;                   // 本次操作是否出错。
    String errorCode;             // 本次操作错误码。
    String operation;             // 本次操作的 API。
    String reason;                // 本次操作错误原因简述。
}
```

你可以通过检索 `errorCode` 字段的[错误码](/zh-CN/realtime-media/rtm/build/troubleshooting)了解错误原因，并找到对应的解决方法。

- 如果该方法调用成功，元组的第二项将返回一个 ` AcquireLockResult` 类型的数据，定义如下：

  ```dart
  class AcquireLockResult {
      final String channelName;                           // 频道名称
      final RtmChannelType channelType;                   // 频道类型
      final String lockName;                              // 锁的名称
      final String errorDetails;                          // 出错原因
  }
  ```

## releaseLock [#releaselock]

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

当用户不再需要持有某把锁时，用户可以在客户端调用 `releaseLock` 方法主动释放锁。成功释放后，频道中的其他用户会收到 `lockReleased` 类型的 `lock` 事件，详见[事件监听](/zh-CN/api-reference/rtm/flutter/configuration#事件监听)。

此时，如果其他用户想要获取该锁，可以在客户端调用 `acquireLock` 方法参与竞争。新参与获取锁的用户和之前设置 `retry` 属性自动尝试获取锁的用户的竞争优先级相同。

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

你可以通过以下方式调用 `releaseLock` 方法：

```dart
Future<(RtmStatus, ReleaseLockResult?)> releaseLock(
    String channelName,
    RtmChannelType channelType,
    String lockName
);
```

| 参数 | 类型 | 必填 | 默认值 | 描述 |
| --- | --- | --- | --- | --- |
| `channelName` | String | 必填 | - | 频道名称。 |
| `channelType` | `RtmChannelType` | 必填 | - | 频道类型。详见 [`RtmChannelType`](/zh-CN/api-reference/rtm/flutter/enumv#channeltype)。 |
| `lockName` | String | 必填 | - | 锁的名称。 |

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

```dart
var (status,response) =
    await rtmClient.getLock.releaseLock("myChannel", RtmChannelType.message, "myLock");

if (status.error == true) {
    print(status);
} else {
    print(response);
}
```

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

调用此方法，会返回 `Future<(RtmStatus,  ReleaseLockResult?)>` 类型的元组数据。

- 无论该方法是否调用成功，元组的第一项都会返回一个 `RtmStatus` 类型的数据，其中字段定义如下：

```dart
class RtmStatus {
    bool error;                   // 本次操作是否出错。
    String errorCode;             // 本次操作错误码。
    String operation;             // 本次操作的 API。
    String reason;                // 本次操作错误原因简述。
}
```

你可以通过检索 `errorCode` 字段的[错误码](/zh-CN/realtime-media/rtm/build/troubleshooting)了解错误原因，并找到对应的解决方法。

- 如果该方法调用成功，元组的第二项将返回一个 ` ReleaseLockResult` 类型的数据，定义如下：

  ```dart
  class ReleaseLockResult {
      final String channelName;                           // 频道名称
      final RtmChannelType channelType;                   // 频道类型
      final String lockName;                              // 锁的名称
  }
  ```

## revokeLock [#revokelock]

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

当锁被占用时，为保证你的业务不受影响，你可能需要收回该锁，并让其他用户有机会获取该锁。调用 `revokeLock` 收回被占用的锁。成功收回后，频道中的所有用户会收到 `lockReleased` 类型的 `lock` 事件，详见[事件监听](/zh-CN/api-reference/rtm/flutter/configuration#事件监听)。

此时，如果其他用户想要获取该锁，可以在客户端调用 `acquireLock` 方法参与竞争。新参与获取锁的用户和之前设置 `retry` 属性自动尝试获取锁的用户的竞争优先级相同。

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

你可以通过以下方式调用 `revokeLock` 方法：

```dart
Future<(RtmStatus, RevokeLockResult?)> revokeLock(
    String channelName,
    RtmChannelType channelType,
    String lockName,
    String owner
);
```

| 参数 | 类型 | 必填 | 默认值 | 描述 |
| --- | --- | --- | --- | --- |
| `channelName` | String | 必填 | - | 频道名称。 |
| `channelType` | `RtmChannelType` | 必填 | - | 频道类型。详见 [`RtmChannelType`](/zh-CN/api-reference/rtm/flutter/enumv#channeltype)。 |
| `lockName` | String | 必填 | - | 锁的名称。 |
| `owner` | String | 必填 | - | 拥有锁的用户 ID。 |

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

```dart
var (status,response) = await rtmClient.getLock.revokeLock("myChannel", RtmChannelType.message, "myLock", "Tony");

if (status.error == true) {
    print(status);
} else {
    print(response);
}
```

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

调用此方法，会返回 `Future<(RtmStatus, RevokeLockResult?)>` 类型的元组数据。

- 无论该方法是否调用成功，元组的第一项都会返回一个 `RtmStatus` 类型的数据，其中字段定义如下：

```dart
class RtmStatus {
    bool error;                   // 本次操作是否出错。
    String errorCode;             // 本次操作错误码。
    String operation;             // 本次操作的 API。
    String reason;                // 本次操作错误原因简述。
}
```

你可以通过检索 `errorCode` 字段的[错误码](/zh-CN/realtime-media/rtm/build/troubleshooting)了解错误原因，并找到对应的解决方法。

- 如果该方法调用成功，元组的第二项将返回一个 `RevokeLockResult` 类型的数据，定义如下：

  ```dart
  class RevokeLockResult {
      final String channelName;                           // 频道名称
      final RtmChannelType channelType;                   // 频道类型
      final String lockName;                              // 锁的名称
  }
  ```

## getLocks [#getlocks]

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

如果你需要查询频道中锁的数量、名称、使用者、过期时间等信息，在客户端调用 `getLocks` 方法。

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

你可以通过以下方式调用 `getLocks` 方法：

```dart
Future<(RtmStatus, GetLocksResult?)> getLocks(
    String channelName,
    RtmChannelType channelType
);
```

| 参数 | 类型 | 必填 | 默认值 | 描述 |
| --- | --- | --- | --- | --- |
| `channelName` | String | 必填 | - | 频道名称。 |
| `channelType` | `RtmChannelType` | 必填 | - | 频道类型。详见 [`RtmChannelType`](/zh-CN/api-reference/rtm/flutter/enumv#channeltype)。 |

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

```dart
var (status,response) =
    await rtmClient.getLock.getLocks("myChannel", RtmChannelType.message);

if (status.error == true) {
    print(status);
} else {
    print(response);
}
```

### 返回值 [#返回值-4]

调用此方法，会返回 `Future<(RtmStatus,  GetLocksResult?)>` 类型的元组数据。

- 无论该方法是否调用成功，元组的第一项都会返回一个 `RtmStatus` 类型的数据，其中字段定义如下：

```dart
class RtmStatus {
    bool error;                   // 本次操作是否出错。
    String errorCode;             // 本次操作错误码。
    String operation;             // 本次操作的 API。
    String reason;                // 本次操作错误原因简述。
}
```

你可以通过检索 `errorCode` 字段的[错误码](/zh-CN/realtime-media/rtm/build/troubleshooting)了解错误原因，并找到对应的解决方法。

- 如果该方法调用成功，元组的第二项将返回一个 ` GetLocksResult` 类型的数据，定义如下：

  ```dart
  class GetLocksResult {
      final String channelName;                           // 频道名称
      final RtmChannelType channelType;                   // 频道类型
      final List<LockDetail> lockDetailList;              // 锁的详情
      final int count;                                    // 锁的数量
  }
  ```

## removeLock [#removelock]

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

如果你不再需要频道中的某把锁，你可以调用 `removeLock` 方法删除该锁。成功删除锁后，频道中的所有用户会收到 `lockRemoved` 类型的 `lock` 事件通知，详见[事件监听](/zh-CN/api-reference/rtm/flutter/configuration#事件监听)。

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

你可以通过以下方式调用 `removeLock` 方法：

```dart
Future<(RtmStatus, RemoveLockResult?)> removeLock(
    String channelName,
    RtmChannelType channelType,
    String lockName
);
```

| 参数 | 类型 | 必填 | 默认值 | 描述 |
| --- | --- | --- | --- | --- |
| `channelName` | String | 必填 | - | 频道名称。 |
| `channelType` | `RtmChannelType` | 必填 | - | 频道类型。详见 [`RtmChannelType`](/zh-CN/api-reference/rtm/flutter/enumv#channeltype)。 |
| `lockName` | String | 必填 | - | 锁的名称。 |

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

```dart
var (status,response) =
    await rtmClient.getLock.removeLock("myChannel", RtmChannelType.message, "myLock");

if (status.error == true) {
    print(status);
} else {
    print(response);
}
```

### 返回值 [#返回值-5]

调用此方法，会返回 `Future<(RtmStatus, RemoveLockResult?)>` 类型的元组数据。

- 无论该方法是否调用成功，元组的第一项都会返回一个 `RtmStatus` 类型的数据，其中字段定义如下：

```dart
class RtmStatus {
    bool error;                   // 本次操作是否出错。
    String errorCode;             // 本次操作错误码。
    String operation;             // 本次操作的 API。
    String reason;                // 本次操作错误原因简述。
}
```

你可以通过检索 `errorCode` 字段的[错误码](/zh-CN/realtime-media/rtm/build/troubleshooting)了解错误原因，并找到对应的解决方法。

- 如果该方法调用成功，元组的第二项将返回一个 `RemoveLockResult` 类型的数据，定义如下：

  ```dart
  class RemoveLockResult {
      final String channelName;                           // 频道名称
      final RtmChannelType channelType;                   // 频道类型
      final String lockName;                              // 锁的名称
  }
  ```
