Presence
Presence 提供监控用户上线、下线及用户历史状态变更通知的能力。通过 Presence 功能,你可以实时获取以下信息:
- 用户加入或离开指定频道的实时事件通知
- 自定义临时用户状态及其变更实时事件通知
- 查询指定用户加入或订阅了哪些频道
- 查询指定频道有哪些用户加入及其用户临时状态数据
Presence 能力适用于 Message Channel 和 Stream Channel。
whoNow
接口描述
调用 whoNow
方法,你可以实时查询指定频道的在线用户数量、在线用户列表及在线用户的临时状态等信息。
接口方法
你可以通过以下方式调用 whoNow
方法:
virtual void whoNow(const char* channelName, RTM_CHANNEL_TYPE channelType, const PresenceOptions& options, uint64_t& requestId) = 0;
参数 | 类型 | 是否必填 | 默认值 | 描述 |
---|---|---|---|---|
channelName | const char* | 必填 | - | 频道名称。 |
channelType | RTM_CHANNEL_TYPE | 必填 | - | 频道类型。详见 RTM_CHANNEL_TYPE 。 |
options | const PresenceOptions& | 必填 | - | 查询附加选项。 |
requestId | uint64_t& | 必填 | - | (输出参数)请求标识符,后续用于识别和处理相应的请求。 |
PresenceOptions
数据类型包含以下属性:
属性 | 类型 | 是否必填 | 默认值 | 描述 |
---|---|---|---|---|
includeUserId | bool | 选填 | true | 返回结果中是否包含在线成员的用户 ID。 |
includeState | bool | 选填 | false | 返回结果中是否包含在线用户的临时状态数据。 |
page | const char* | 选填 | NULL | 页码书签。如果不填写,则 SDK 默认返回第一页结果。你可以在返回值中查看是否还有下一页。 |
异步回调
调用该方法后,SDK 会触发 onWhoNowResult
回调并通过以下参数返回 API 调用结果:
参数 | 类型 | 描述 |
---|---|---|
requestId | const uint64_t | 请求标识符。 |
userStateList | const UserState* | 频道在线用户及其临时状态信息列表。 |
count | const size_t | UserState 列表长度,当 whoNow 属性中 includeUserId 、includeState 属性都设置为 false 时,此值表示频道当前总在线人数。 |
nextPage | const char* | 下一页书签。通过该属性可以确认是否有下一页:
|
errorCode | RTM_ERROR_CODE | 错误码,详见错误排查。 |
UserState
数据类型包含以下属性:
属性 | 类型 | 描述 |
---|---|---|
userId | const char* | 用户 ID。 |
states | const StateItem* | 频道在线用户及其临时状态信息列表。 |
statesCount | size_t | 用户状态的数量。 |
StateItem
数据类型包含以下属性:
属性 | 类型 | 描述 |
---|---|---|
key | const char* | 用户状态的键。如果指定的键已经存在,则该键的值会被新值覆盖;如果指定的键不存在,则 SDK 会新增该键/值对。 |
value | const char* | 用户状态的值。 |
基本用法
// 方法调用
PresenceOptions options;
options.includeState = true;
options.includeUserId =true;
options.page = "yourBookMark";
uint64_t requestId;
rtmClient->getPresence()->whoNow("channelName", RTM_CHANNEL_TYPE_MESSAGE, options, requestId);
// 异步回调
class RtmEventHandler : public IRtmEventHandler {
void onWhoNowResult(const uint64_t requestId, const UserState *userStateList, const size_t count, const char *nextPage, RTM_ERROR_CODE errorCode) override {
if (errorCode != RTM_ERROR_OK) {
printf("who now failed error is %d reason is %s\n", errorCode, getErrorReason(errorCode));
} else {
printf("who now success\n");
for (int i = 0 ;i < count; i++) {
printf("user: %s\n", userStateList[i].userId);
for (int j = 0 ; j < userStateList[i].statesCount; j++) {
printf("key: %s value: %s\n", userStateList[i].states[j].key, userStateList[i].states[j].value);
}
}
}
}
};
whereNow
接口描述
在数据统计、App 调试等场景中,你可能需要了解指定用户订阅或加入的所有频道。调用 whereNow
方法,你可以实时获取指定用户所在频道的列表。
接口方法
你可以通过以下方式调用 whereNow
方法:
virtual void whereNow(const char* userId, uint64_t& requestId) = 0;
参数 | 类型 | 是否必填 | 默认值 | 描述 |
---|---|---|---|---|
userId | const char* | 必填 | - | 用户 ID。 |
requestId | uint64_t& | 必填 | - | (输出参数)请求标识符,后续用于识别和处理相应的请求。 |
异步回调
调用该方法后,SDK 会触发 onWhereNowResult
回调并通过以下参数返回 API 调用结果:
参数 | 类型 | 描述 |
---|---|---|
requestId | const uint64_t | 请求标识符。 |
channels | const ChannelInfo* | 频道信息。 |
count | const size_t | 频道数量。 |
errorCode | RTM_ERROR_CODE | 错误码,详见错误排查。 |
ChannelInfo
数据类型包含以下属性:
属性 | 类型 | 描述 |
---|---|---|
channelName | const char* | 频道名称。 |
channelType | RTM_CHANNEL_TYPE | 频道类型。详见 RTM_CHANNEL_TYPE 。 |
基本用法
// 方法调用
uint64_t requestId;
rtmClient->getPresence()->whereNow("tony", requestId);
// 异步回调
class RtmEventHandler : public IRtmEventHandler {
void onWhereNowResult(const uint64_t requestId, const ChannelInfo *channels, const size_t count, RTM_ERROR_CODE errorCode) override {
if (errorCode != RTM_ERROR_OK) {
printf("where now failed error is %d reason is %s\n", errorCode, getErrorReason(errorCode));
} else {
printf("where now success\n");
for (int i = 0; i < count; i++) {
printf("channel: %s channel type: %d\n", channels[i].channelName, channels[i].channelType);
}
}
}
};
setState
接口描述
为满足不同业务场景对用户状态的设置需求,RTM 提供 setState
方法自定义临时用户状态。用户可以为自己添加分数、游戏状态、位置、心情、连麦状态等自定义状态。
设置成功后,只要用户保持订阅频道并一直在线,自定义状态就会在频道中持续存在。setState
方法设置的是临时用户状态,当用户离开频道或断开与 RTM 的连接时,状态会消失。如果需要在重新加入频道或者重新连接时恢复用户状态,你需要实时在本地缓存该数据。如果你希望永久保存用户状态数据,声网推荐改用 Storage 功能的 setUserMetadata
方法。
如果用户修改了临时用户状态,RTM 会实时触发 RTM_PRESENCE_EVENT_TYPE_REMOTE_STATE_CHANGED
类型的 onPresenceEvent
事件通知。你可以通过订阅频道并配置对应属性来接收该事件。
接口方法
你可以通过以下方式调用 setState
方法:
virtual void setState(const char* channelName, RTM_CHANNEL_TYPE channelType, const StateItem* items, size_t count, uint64_t& requestId) = 0;
参数 | 类型 | 是否必填 | 默认值 | 描述 |
---|---|---|---|---|
channelName | const char* | 必填 | - | 频道名称 |
channelType | RTM_CHANNEL_TYPE | 必填 | - | 频道类型。详见 RTM_CHANNEL_TYPE 。 |
items | const StateItem* | 必填 | - | 用户状态。 |
count | size_t | 必填 | - | 用户状态的数量。 |
requestId | uint64_t& | 必填 | - | (输出参数)请求标识符,后续用于识别和处理相应的请求。 |
StateItem
数据类型包含以下属性:
属性 | 类型 | 描述 |
---|---|---|
key | const char* | 用户状态的键。如果指定的键已经存在,则该键的值会被新值覆盖;如果指定的键不存在,则 SDK 会新增该键/值对。 |
value | const char* | 用户状态的值。 |
异步回调
调用该方法后,SDK 会触发 onPresenceSetStateResult
回调并通过以下参数返回 API 调用结果:
参数 | 类型 | 描述 |
---|---|---|
requestId | const uint64_t | 请求标识符。 |
errorCode | RTM_ERROR_CODE | 错误码,详见错误排查。 |
基本用法
// 方法调用
std::vector<StateItem> items;
StateItem item;
item.key = "mood";
item.value = "pumped";
items.push_back(item);
uint64_t requestId;
rtmClient->getPresence()->setState("channelName", RTM_CHANNEL_TYPE_MESSAGE, items.data(), items.size(), requestId);
// 异步回调
class RtmEventHandler : public IRtmEventHandler {
void onPresenceSetStateResult(const uint64_t requestId, RTM_ERROR_CODE errorCode) override {
if (errorCode != RTM_ERROR_OK) {
printf("SetState failed error is %d reason is %s\n", errorCode, getErrorReason(errorCode));
} else {
printf("SetState success\n");
}
}
};
getState
接口描述
如需获取指定频道中指定用户的临时用户状态,你可以调用 getState
方法。
接口方法
你可以通过以下方式调用 getState
方法:
virtual void getState(const char* channelName, RTM_CHANNEL_TYPE channelType, const char* userId, uint64_t& requestId) = 0;
参数 | 类型 | 是否必填 | 默认值 | 描述 |
---|---|---|---|---|
channelName | const char* | 必填 | - | 频道名称。 |
channelType | RTM_CHANNEL_TYPE | 必填 | - | 频道类型。详见 RTM_CHANNEL_TYPE 。 |
userId | const char* | 必填 | - | 用户 ID。 |
requestId | uint64_t& | 必填 | - | (输出参数)请求标识符,后续用于识别和处理相应的请求。 |
异步回调
调用该方法后,SDK 会触发 onPresenceGetStateResult
回调并通过以下参数返回 API 调用结果:
参数 | 类型 | 描述 |
---|---|---|
requestId | const uint64_t | 请求标识符。 |
state | const UserState& | 频道在线用户及其临时状态信息列表。 |
errorCode | RTM_ERROR_CODE | 错误码,详见错误排查。 |
UserState
数据类型包含以下属性:
属性 | 类型 | 描述 |
---|---|---|
userId | const char* | 用户 ID。 |
states | const StateItem* | 频道在线用户及其临时状态信息列表。 |
statesCount | size_t | 用户状态的数量。 |
StateItem
数据类型包含以下属性:
属性 | 类型 | 描述 |
---|---|---|
key | const char* | 用户状态的键。如果指定的键已经存在,则该键的值会被新值覆盖;如果指定的键不存在,则 SDK 会新增该键/值对。 |
value | const char* | 用户状态的值。 |
基本用法
// 方法调用
uint64_t requestId;
rtmClient->getPresence()->getState("channelName", RTM_CHANNEL_TYPE_MESSAGE, "tony", requestId);
// 异步回调
class RtmEventHandler : public IRtmEventHandler {
void onPresenceGetStateResult(const uint64_t requestId, const UserState &state, RTM_ERROR_CODE errorCode) override {
if (errorCode != RTM_ERROR_OK) {
printf("GetState failed error is %d reason is %s\n", errorCode, getErrorReason(errorCode));
} else {
printf("GetState user id: %s success\n", state.userId);
for (int i = 0; i < state.statesCount; i++) {
printf("key: %s, value: %s\n", state.states[i].key, state.states[i].value);
}
}
}
};
removeState
接口描述
当不再需要某个临时用户状态时,你可以调用 removeState
方法删除自己的一个或多个临时状态。
成功删除用户状态后,订阅该频道且开启 Presence 事件监听的用户会收到 RTM_PRESENCE_EVENT_TYPE_REMOTE_STATE_CHANGED
类型的 onPresenceEvent
事件通知,详见事件监听。
接口方法
你可以通过以下方式调用 removeState
方法:
virtual void removeState(const char* channelName, RTM_CHANNEL_TYPE channelType, const char** keys, size_t count, uint64_t& requestId) = 0;
参数 | 类型 | 是否必填 | 默认值 | 描述 |
---|---|---|---|---|
channelName | const char* | 必填 | - | 频道名称 |
channelType | RTM_CHANNEL_TYPE | 必填 | - | 频道类型。详见 RTM_CHANNEL_TYPE 。 |
keys | const char** | 必填 | - | 需要删除状态的 key 列表。如果不填写,则删除全部状态。 |
count | size_t | 必填 | - | key 的数量。 |
requestId | uint64_t& | 必填 | - | (输出参数)请求标识符,后续用于识别和处理相应的请求。 |
异步回调
调用该方法后,SDK 会触发 onPresenceRemoveStateResult
回调并通过以下参数返回 API 调用结果:
参数 | 类型 | 描述 |
---|---|---|
requestId | const uint64_t | 请求标识符。 |
errorCode | RTM_ERROR_CODE | 错误码,详见错误排查。 |
基本用法
// 方法调用
std::vector<const char*> keys;
keys.push_back("key0");
keys.push_back("key1");
keys.push_back("key2");
uint64_t requestId;
rtmClient->getPresence()->removeState("channelName", RTM_CHANNEL_TYPE_MESSAGE, keys.data(), keys.size(), requestId);
// 异步回调
class RtmEventHandler : public IRtmEventHandler {
void onPresenceRemoveStateResult(const uint64_t requestId, RTM_ERROR_CODE errorCode) override {
if (errorCode != RTM_ERROR_OK) {
printf("RemoveState failed error is %d reason is %s\n", errorCode, getErrorReason(errorCode));
} else {
printf("RemoveState success\n");
}
}
};