在线状态
用户至少有一台设备与服务端保持着长连接,就是在线。用户在客户端登录后,客户端 SDK 会建立长连接并保持;只登录、没有建立长连接的设备不算在线。在线状态包括:
- 是否在线;
- 在线的平台:如
ios、windows,取值与登录时上报的平台相同(ios、android、harmony、web、windows、macos、linux、mini_program、other); - 最近一次离线的时间:用户离线时才有。
你的业务服务端可以用本页的接口查询任意用户的在线状态,例如判断用户是否在线,再决定是否改用短信、邮件等方式通知他。需要实时得知用户上线、下线时,可以订阅事件回调 presence.changed,它是尽力而为的事件,可能丢失,关键的判断请以本页接口的查询结果为准。
- 后台也算在线:移动端 App 切到后台后,只要连接还在,仍算在线。本页接口不区分前台和后台。
- 离线的判定有延迟:用户正常退出或关闭连接时立即变为离线;设备异常断网时,服务端在连接空闲超时后才发现(默认前台 90 秒、后台 360 秒),这段时间内仍显示在线。网络切换时新连接会替换旧连接,不会出现“先离线再上线”。
- 数据保留:最近离线时间保留 30 天,30 天内没有上线过的用户
last_seen_at为null、version为 0。
与应用运行策略的关系
运行策略中与在线状态有关的设置只限制客户端(用户之间)查看在线状态,对本页的接口都不生效,服务端总能查询任意用户、看到最近离线时间:
| 策略 | 默认值 | 对客户端的作用 |
|---|---|---|
presence_enabled | 关闭 | 开启后,客户端才能查询和订阅其他用户的在线状态 |
presence_scope | friends | 客户端能看到谁的在线状态:friends 只能看好友的,all 可以看应用内任何用户的 |
presence_last_seen_visible | 开启 | 关闭后,客户端只能看到对方是否在线,看不到最近离线时间 |
设置方法见运行策略。
批量查询在线状态
一次查询最多 100 个用户的在线状态。无论查询多少个用户,都只计一次调用。
POST
/{org_name}/{app_name}/presence/query路径参数
org_name、app_name 见接入概述。
请求体
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
usernames | Array<String> | 是 | 要查询的用户名,1 到 100 个。不区分大小写,重复的只返回一次 |
请求示例
bash
curl -X POST "$IM_API/$ORG/$APP/presence/query" \
-H "Authorization: Bearer $APP_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"usernames": ["alice", "bob", "carol", "nobody"]
}'响应
成功返回 200 OK,items 中每一项为在线状态对象,顺序与请求中的一致;不存在或已删除的用户不出现在结果中。
json
{
"items": [
{
"username": "alice",
"online": true,
"platforms": ["ios", "windows"],
"last_seen_at": null,
"version": 1790968803807
},
{
"username": "bob",
"online": false,
"platforms": [],
"last_seen_at": "2026-10-02T19:12:04.903Z",
"version": 1790968324903
},
{
"username": "carol",
"online": false,
"platforms": [],
"last_seen_at": null,
"version": 0
}
]
}示例中 alice 在 iOS 和 Windows 上都在线,bob 已离线,carol 从未上线过。
错误
| HTTP 状态码 | code | 说明 |
|---|---|---|
| 400 | invalid_argument | usernames 为空或超过 100 个,details.field 为 usernames |
| 500 | internal | details.reason 为 dependency_unavailable:在线状态服务暂时不可用,按 Retry-After 响应头等待后重试 |
查询用户的在线状态
查询单个用户的在线状态。
GET
/{org_name}/{app_name}/users/{username}/presence路径参数
org_name、app_name 见接入概述。
| 参数 | 类型 | 说明 |
|---|---|---|
username | String | 用户名,不区分大小写 |
请求示例
bash
curl "$IM_API/$ORG/$APP/users/alice/presence" \
-H "Authorization: Bearer $APP_TOKEN"响应
成功返回 200 OK,响应体为在线状态对象。
json
{
"username": "alice",
"online": true,
"platforms": ["ios", "windows"],
"last_seen_at": null,
"version": 1790968803807
}这个接口只返回在线的平台,不返回每台设备的信息。用户登录了哪些设备见查询登录设备(登录不等于在线);每条长连接的平台、前后台状态、IP 地址和连接时间,可以在控制台的用户详情中查看。
错误
| HTTP 状态码 | code | 说明 |
|---|---|---|
| 404 | not_found | 用户不存在或已删除 |
| 500 | internal | details.reason 为 dependency_unavailable:在线状态服务暂时不可用,按 Retry-After 响应头等待后重试 |
数据结构
在线状态对象
| 字段 | 类型 | 说明 |
|---|---|---|
username | String | 用户名 |
online | Boolean | 是否在线:至少有一台设备保持着长连接(包括在后台的设备) |
platforms | Array<String> | 在线的平台,按字母排序,同一平台有多台设备在线时只出现一次;离线时为空数组 |
last_seen_at | String | 最近一次变为离线的时间。在线时为 null;30 天内没有上线过的用户也为 null |
version | Number | 在线状态的版本号,每次变化(上线、离线、在线的平台增减)都会变大,可以用来判断两次查询之间是否有变化、丢弃较旧的结果。从未上线过或 30 天没有变化的用户为 0 |
json
{
"username": "bob",
"online": false,
"platforms": [],
"last_seen_at": "2026-10-02T19:12:04.903Z",
"version": 1790968324903
}