Lock
临界资源一次只能供一个进程使用,如果不同的进程之间共享了某个临界资源,则各进程需要采取互斥的方式来防止彼此干扰。RTM 提供一整套 Lock 的方案,通过控制分布式系统的不同进程,你可以解决用户在访问共享资源时的竞争问题。
客户端 SDK 具备设置、删除、撤销锁的能力,我们建议你根据实际业务需求控制端侧对锁的操作权限。
setLock
接口描述
你需要配置锁的名称、过期时间 TTL 等属性,然后调用 setLock 方法进行配置。
配置成功后,频道中的所有用户会收到 LOCK_SET 类型的 lock 事件通知,详见事件监听。
接口方法
你可以通过以下方式调用 setLock 方法:
async setLock(
channelName: string,
channelType: RtmChannelType,
lockName: string,
options?: SetLockOptions
): Promise<SetLockResponse>
| 参数 | 类型 | 是否必填 | 默认值 | 描述 |
|---|---|---|---|---|
channelName | string | 必填 | - | 频道名称。 |
channelType | RtmChannelType | 必填 | - | 频道类型。详见 RtmChannelType。 |
lockName | string | 必填 | - | 锁的名称。 |
options | SetLockOptions | 选填 | {} | 锁的配置选项。 |
SetLockOptions 数据类型包含以下属性:
| 属性 | 类型 | 是否必填 | 默认值 | 描述 |
|---|---|---|---|---|
ttl | number | 选填 | 10 | 设置锁的过期时间。单位为秒,取值范围为 [10,300]。当使用这把锁的用户掉线时,如果用户在过期时间之内重新回到频道,则该用户依旧可以使用锁;否则,该用户的锁会被释放,监听了 lock 事件通知的用户会收到 LOCK_RELEASED 事件。 |
返回值
该方法返回一个 Promise,成功时 resolve 并返回 SetLockResponse 对象,失败时 reject 并抛出 RtmError 异常。
SetLockResponse 数据结构如下:
| 属性 | 类型 | 描述 |
|---|---|---|
timestamp | number | 操作的时间戳(保留字段,供未来使用)。 |
channelName | string | 频道名称。 |
channelType | RtmChannelType | 频道类型,详见 RtmChannelType。 |
lockName | string | Lock 名称。 |
基本用法
import { RtmClient, RtmError, RtmChannelType } from '@shengwang/rtm-full';
try {
const response = await rtmClient.lock.setLock('channelName', RtmChannelType.MESSAGE, 'lockName', { ttl: 30 });
console.log('Lock set successfully');
console.log('Lock name:', response.lockName);
console.log('Channel:', response.channelName);
} catch (error) {
if (error instanceof RtmError) {
console.error('setLock failed:', error.errorCode, error.reason);
}
}
acquireLock
接口描述
成功配置 Lock 后,你可以在客户端调用 acquireLock 方法获取锁的使用权。
成功获取锁后,频道中的其他用户会收到 LOCK_ACQUIRED 类型的 lock 事件通知,详见事件监听。
接口方法
你可以通过以下方式调用 acquireLock 方法:
async acquireLock(
channelName: string,
channelType: RtmChannelType,
lockName: string,
options?: AcquireLockOptions
): Promise<AcquireLockResponse>
| 参数 | 类型 | 是否必填 | 默认值 | 描述 |
|---|---|---|---|---|
channelName | string | 必填 | - | 频道名称。 |
channelType | RtmChannelType | 必填 | - | 频道类型。详见 RtmChannelType。 |
lockName | string | 必填 | - | 锁的名称。 |
options | AcquireLockOptions | 选填 | {} | 获取锁的配置选项。 |
AcquireLockOptions 数据类型包含以下属性:
| 属性 | 类型 | 是否必填 | 默认值 | 描述 |
|---|---|---|---|---|
retry | boolean | 选填 | false | 设置在获取锁失败后是否继续尝试,直到成功获取或退出频道为止。 |
返回值
该方法返回一个 Promise,成功时 resolve 并返回 AcquireLockResponse 对象,失败时 reject 并抛出 RtmError 异常。
AcquireLockResponse 数据结构如下:
| 属性 | 类型 | 描述 |
|---|---|---|
timestamp | number | 操作的时间戳(保留字段,供未来使用)。 |
channelName | string | 频道名称。 |
channelType | RtmChannelType | 频道类型,详见 RtmChannelType。 |
lockName | string | Lock 名称。 |
errorDetails | string | 错误详情。 |
基本用法
import { RtmClient, RtmError, RtmChannelType } from '@shengwang/rtm-full';
try {
const response = await rtmClient.lock.acquireLock('channelName', RtmChannelType.MESSAGE, 'lockName', { retry: false });
console.log('Lock acquired successfully');
console.log('Lock name:', response.lockName);
console.log('Channel:', response.channelName);
} catch (error) {
if (error instanceof RtmError) {
console.error('acquireLock failed:', error.errorCode, error.reason);
}
}
releaseLock
接口描述
当用户不再需要持有某把锁时,用户可以在客户端调用 releaseLock 方法主动释放锁。
成功释放后,频道中的其他用户会收到 LOCK_RELEASED 类型的 lock 事件,详见事件监听。
此时,如果其他用户想要获取该锁,可以在客户端调用 acquireLock 方法参与竞争。新参与获取锁的用户和之前设置 retry 属性自动尝试获取锁的用户的竞争优先级相同。
接口方法
你可以通过以下方式调用 releaseLock 方法:
async releaseLock(
channelName: string,
channelType: RtmChannelType,
lockName: string
): Promise<ReleaseLockResponse>
| 参数 | 类型 | 是否必填 | 默认值 | 描述 |
|---|---|---|---|---|
channelName | string | 必填 | - | 频道名称。 |
channelType | RtmChannelType | 必填 | - | 频道类型。详见 RtmChannelType。 |
lockName | string | 必填 | - | 锁的名称。 |
返回值
该方法返回一个 Promise,成功时 resolve 并返回 ReleaseLockResponse 对象,失败时 reject 并抛出 RtmError 异常。
ReleaseLockResponse 数据结构如下:
| 属性 | 类型 | 描述 |
|---|---|---|
timestamp | number | 操作的时间戳(保留字段,供未来使用)。 |
channelName | string | 频道名称。 |
channelType | RtmChannelType | 频道类型,详见 RtmChannelType。 |
lockName | string | Lock 名称。 |
基本用法
import { RtmClient, RtmError, RtmChannelType } from '@shengwang/rtm-full';
try {
const response = await rtmClient.lock.releaseLock('channelName', RtmChannelType.MESSAGE, 'lockName');
console.log('Lock released successfully');
console.log('Lock name:', response.lockName);
console.log('Channel:', response.channelName);
} catch (error) {
if (error instanceof RtmError) {
console.error('releaseLock failed:', error.errorCode, error.reason);
}
}
revokeLock
接口描述
当锁被占用时,为保证你的业务不受影响,你可能需要收回该锁,并让其他用户有机会获取该锁。调用 revokeLock 收回被占用的锁。
成功收回后,频道中的所有用户会收到 LOCK_RELEASED 类型的 lock 事件,详见事件监听。
此时,如果其他用户想要获取该锁,可以在客户端调用 acquireLock 方法参与竞争。新参与获取锁的用户和之前设置 retry 属性自动尝试获取锁的用户的竞争优先级相同。
接口方法
你可以通过以下方式调用 revokeLock 方法:
async revokeLock(
channelName: string,
channelType: RtmChannelType,
lockName: string,
owner: string
): Promise<RevokeLockResponse>
| 参数 | 类型 | 是否必填 | 默认值 | 描述 |
|---|---|---|---|---|
channelName | string | 必填 | - | 频道名称。 |
channelType | RtmChannelType | 必填 | - | 频道类型。详见 RtmChannelType。 |
lockName | string | 必填 | - | 锁的名称。 |
owner | string | 必填 | - | 拥有锁的用户 ID。 |
返回值
该方法返回一个 Promise,成功时 resolve 并返回 RevokeLockResponse 对象,失败时 reject 并抛出 RtmError 异常。
RevokeLockResponse 数据结构如下:
| 属性 | 类型 | 描述 |
|---|---|---|
timestamp | number | 操作的时间戳(保留字段,供未来使用)。 |
channelName | string | 频道名称。 |
channelType | RtmChannelType | 频道类型,详见 RtmChannelType。 |
lockName | string | Lock 名称。 |
基本用法
import { RtmClient, RtmError, RtmChannelType } from '@shengwang/rtm-full';
try {
const response = await rtmClient.lock.revokeLock('channelName', RtmChannelType.MESSAGE, 'lockName', 'tony');
console.log('Lock revoked successfully');
console.log('Lock name:', response.lockName);
console.log('Channel:', response.channelName);
} catch (error) {
if (error instanceof RtmError) {
console.error('revokeLock failed:', error.errorCode, error.reason);
}
}
getLocks
接口描述
如果你需要查询频道中锁的数量、名称、使用者、过期时间等信息,在客户端调用 getLocks 方法。
接口方法
你可以通过以下方式调用 getLocks 方法:
async getLocks(
channelName: string,
channelType: RtmChannelType
): Promise<GetLocksResponse>
| 参数 | 类型 | 是否必填 | 默认值 | 描述 |
|---|---|---|---|---|
channelName | string | 必填 | - | 频道名称。 |
channelType | RtmChannelType | 必填 | - | 频道类型。详见 RtmChannelType。 |
返回值
该方法返回一个 Promise,成功时 resolve 并返回 GetLocksResponse 对象,失败时 reject 并抛出 RtmError 异常。
GetLocksResponse 数据结构如下:
| 属性 | 类型 | 描述 |
|---|---|---|
timestamp | number | 操作的时间戳(保留字段,供未来使用)。 |
channelName | string | 频道名称。 |
channelType | RtmChannelType | 频道类型,详见 RtmChannelType。 |
lockDetails | LockDetail[] | Lock 详情数组。 |
LockDetail 数据类型包含以下属性:
| 属性 | 类型 | 描述 |
|---|---|---|
lockName | string | Lock 的名称。 |
owner | string | 拥有锁的用户 ID。 |
ttl | number | 锁的过期时间。当使用这把锁的用户掉线时,如果用户在过期时间之内重新回到频道,则该用户依旧可以使用锁;否则,该用户的锁会被释放,监听了 lock 事件通知的用户会收到 LOCK_RELEASED 事件。 |
基本用法
import { RtmClient, RtmError, RtmChannelType } from '@shengwang/rtm-full';
try {
const response = await rtmClient.lock.getLocks('channelName', RtmChannelType.MESSAGE);
console.log('Locks retrieved successfully');
console.log('Total locks:', response.lockDetails.length);
console.log('Channel:', response.channelName);
response.lockDetails.forEach((lock) => {
console.log(`Lock: ${lock.lockName}`);
console.log(` Owner: ${lock.owner || 'none'}`);
console.log(` TTL: ${lock.ttl}s`);
});
} catch (error) {
if (error instanceof RtmError) {
console.error('getLocks failed:', error.errorCode, error.reason);
}
}
removeLock
接口描述
如果你不再需要频道中的某把锁,你可以调用 removeLock 方法删除该锁。
成功删除锁后,频道中的所有用户会收到 LOCK_REMOVED 类型的 lock 事件通知,详见事件监听。
接口方法
你可以通过以下方式调用 removeLock 方法:
async removeLock(
channelName: string,
channelType: RtmChannelType,
lockName: string
): Promise<RemoveLockResponse>
| 参数 | 类型 | 是否必填 | 默认值 | 描述 |
|---|---|---|---|---|
channelName | string | 必填 | - | 频道名称。 |
channelType | RtmChannelType | 必填 | - | 频道类型。详见 RtmChannelType。 |
lockName | string | 必填 | - | 锁的名称。 |
返回值
该方法返回一个 Promise,成功时 resolve 并返回 RemoveLockResponse 对象,失败时 reject 并抛出 RtmError 异常。
RemoveLockResponse 数据结构如下:
| 属性 | 类型 | 描述 |
|---|---|---|
timestamp | number | 操作的时间戳(保留字段,供未来使用)。 |
channelName | string | 频道名称。 |
channelType | RtmChannelType | 频道类型,详见 RtmChannelType。 |
lockName | string | Lock 名称。 |
基本用法
import { RtmClient, RtmError, RtmChannelType } from '@shengwang/rtm-full';
try {
const response = await rtmClient.lock.removeLock('channelName', RtmChannelType.MESSAGE, 'lockName');
console.log('Lock removed successfully');
console.log('Lock name:', response.lockName);
console.log('Channel:', response.channelName);
} catch (error) {
if (error instanceof RtmError) {
console.error('removeLock failed:', error.errorCode, error.reason);
}
}