用途
Convex Realtime 面向在 Convex 平台上构建实时交互应用的开发者,帮助实现实时数据订阅、乐观 UI 更新、实时分页、在线状态(presence)与输入状态(typing)指示等功能。
主要能力
自动订阅
Convex 中的查询会自动订阅更新。React 组件使用 useQuery 调用查询后,数据变化时会自动刷新,无需手动订阅。示例中通过 useQuery(api.tasks.list, { userId }) 获取任务列表,并在数据未加载完成时显示 Loading。
乐观更新
通过 useMutation(...).withOptimisticUpdate 可在服务端响应前立即更新本地缓存,实现乐观 UI。文档给出三类示例:
- 乐观新增:从 localStore 读取当前任务列表,构造带临时 _id(crypto.randomUUID)和 _creationTime 的乐观任务,并写回本地缓存。
- 乐观删除:读取当前列表后过滤掉待删除任务,再写回本地缓存。
- 乐观切换:读取当前列表后对目标任务取反 completed 状态,再写回本地缓存。
实时分页
使用 paginationOptsValidator 定义分页查询,服务端通过 withIndex、order 和 paginate 返回分页结果。客户端使用 usePaginatedQuery 获取 results、status 和 loadMore,根据 status(如 CanLoadMore、LoadingMore)控制加载更多按钮与加载状态。
在线状态指示
通过 presence 表记录 documentId、documentType、lastSeen,并建立 by_user 与 by_document 索引。heartbeat mutation 在用户身份存在时更新或插入 presence 记录;getActive query 过滤最近五分钟内的记录返回活跃用户。客户端 hook 每 30 秒发送一次心跳,并返回活跃用户列表。
输入状态指示
通过 typing 表记录 channelId、userId、updatedAt。setTyping mutation 根据 isTyping 插入、更新或删除记录;getTyping query 过滤最近十秒内的记录并排除当前用户,返回正在输入的用户 ID 列表。
条件查询
useQuery 支持传入 "skip" 跳过查询,例如当 userId 为 null 时不执行查询,从而避免不必要的订阅。
使用方式
文档以 TypeScript 与 React 代码示例展示各功能的实现方式,涉及 convex/react 的 useQuery、useMutation、usePaginatedQuery,以及 convex/server 的 paginationOptsValidator、convex/values 的 v 等。服务端逻辑定义在 convex 目录下的 schema 与函数文件中。
适用场景
适用于需要实时数据同步的协作类、聊天类、任务管理类应用,例如任务列表实时刷新、消息频道分页加载、文档协作中的在线用户展示与输入状态提示等。
限制与注意事项
文档列出常见陷阱:乐观更新可能过期,应始终校验服务端状态是否符合预期;避免过度订阅,只订阅需要的数据;注意区分 undefined(加载中)与 null(未找到);presence 记录需要清理,建议添加定时任务清理旧记录。
参考链接
- Reactivity: https://docs.convex.dev/client/react
- Optimistic Updates: https://docs.convex.dev/client/react/optimistic-updates
- Pagination: https://docs.convex.dev/database/pagination