|
|
背景
在调研 App Inventor 2 后台推送通知方案时,我们深入分析了 fun123 自研的 Supabase 扩展。Supabase 官方确实提供了 Realtime 实时推送功能,那么当前扩展是否已经封装了这些能力?能否直接用来做推送?
以下是源码级分析结论。
一、Supabase Realtime 三大功能
Supabase 官方提供三种 Realtime 能力:
1. Broadcast(广播)
客户端之间低延迟消息传递。发送方式:
- 客户端库(WebSocket)
- REST API(HTTP POST /realtime/v1/api/broadcast)
- 数据库函数(realtime.send())
2. Presence(在线状态)
跟踪用户在线/离线状态,同步状态数据。
3. Postgres Changes(数据库变更)
监听 PostgreSQL 表的 INSERT/UPDATE/DELETE 操作,实时获取变更数据。支持按 schema、table、event、filter 精确过滤。
关键:三种功能都依赖 WebSocket 长连接(基于 Phoenix Channels 协议),不是 HTTP 请求-响应模式。
二、当前 Supabase 扩展源码分析
扩展包含 4 个子组件:
| 组件 | 网络实现 | API 模式 | | SupabaseAuth | HttpURLConnection | 认证 REST API | | SupabasePgSQL | HttpURLConnection | PostgREST CRUD API | | SupabaseStorage | HttpURLConnection | Storage REST API | | SupabaseFunction | HttpURLConnection | Edge Functions REST API |
核心发现:所有组件都基于 HttpURLConnection(请求-响应模式),没有任何 WebSocket 连接。
源码级验证:
1. SupabaseCore.java 的 import 列表:只有 java.net.HttpURLConnection,没有 WebSocket
2. 所有网络请求通过 executeRequest() 方法封装,使用 HttpURLConnection.openConnection()
3. grep 搜索整个扩展源码:websocket / subscribe / channel / listen / realtime / phoenix 关键词全部无结果
4. 扩展没有使用 @UsesLibraries 注解引入任何外部网络库
5. 对整个 AI2 组件源码 grep WebSocket 关键字,结果为零——整个 AI2 生态没有 WebSocket 实现
结论:当前 Supabase 扩展完全不支持 Realtime 功能。
三、Supabase Realtime 的底层协议
Supabase Realtime 基于 Phoenix Framework 的 Channels 协议:
连接建立
1. 客户端通过 WebSocket 连接到 wss://<project>.supabase.co/realtime/v1/websocket
2. 连接时携带apikey和可选的 Authorization token
3. 连接建立后进入 Phoenix Channels 交互
Phoenix Channels 消息格式
所有消息都是 JSON,包含以下字段:
- topic:频道名称(如 "realtime:public")
- event:事件类型(join / push / reply / heartbeat / presence_diff 等)
- payload:消息内容
- ref:消息引用 ID
核心交互流程
1. join:客户端加入频道(phx_join 事件)
2. heartbeat:每 30 秒发送心跳(phx_heartbeat 事件)
3. push:服务器推送数据(对应 Postgres Changes / Broadcast / Presence 事件)
4. reply:服务器对客户端请求的响应
四、为扩展添加 Realtime 支持的技术方案
方案:新增 SupabaseRealtime 子组件
技术架构:
- 引入 OkHttp WebSocket 客户端(通过 @UsesLibraries 注解打包 okhttp.jar)
- 实现 Phoenix Channels 协议(JSON 消息格式:join/heartbeat/push/reply)
- 封装为 AI2 事件驱动接口
- 配合前台 Service(@UsesServices)保活
积木块 API 设计:
| 类型 | 名称 | 说明 | | 方法 | Connect() | 建立 WebSocket 连接 | | 方法 | Disconnect() | 断开连接 | | 方法 | Subscribe(channel, event) | 订阅频道 | | 方法 | Unsubscribe(channel) | 取消订阅 | | 方法 | Broadcast(channel, event, payload) | 发送广播消息 | | 事件 | OnConnected() | 连接成功 | | 事件 | OnMessage(channel, event, payload) | 收到消息 | | 事件 | OnPostgresChange(table, event, record) | 数据库变更 | | 事件 | OnPresenceChange(key, state) | 在线状态变化 | | 事件 | OnError(message) | 错误回调 |
开发量评估:3-4 周
- OkHttp WebSocket 集成:1 周
- Phoenix Channels 协议实现:1 周
- AI2 事件接口封装:0.5 周
- 前台 Service 保活 + 测试:1 周
- 文档和示例:0.5 周
五、关键限制:Supabase Realtime 不是系统级推送
即使添加了 Realtime 支持,也要明确:
Supabase Realtime = App 内推送(WebSocket 长连接)
- App 必须在运行状态(前台或后台保活)
- App 被系统杀掉 = 收不到消息
- 需要前台 Service + 通知栏显示"App 正在运行"
极光推送 = 系统级推送(操作系统推送通道)
- App 被杀也能收到通知
- 走操作系统推送通道,不依赖 App 进程
- 这是两者最根本的区别
所以:
- 如果需求是"App 在线时实时同步数据" = Supabase Realtime 就够了
- 如果需求是"像微信一样不打开 App 也收到通知" = 必须走系统推送(极光/FCM)
六、利用现有组件模拟实时效果的临时方案
在 Realtime 组件开发完成之前,可以用以下方式模拟:
方案:SupabasePgSQL + Clock 轮询
1. Clock 组件设置 TimerInterval(如 5000 毫秒)
2. Timer 事件中调用 SupabasePgSQL.Query() 查询新数据
3. 比对数据变化,用 NotificationStyle 显示通知
限制:
- 仅 App 在前台时有效(后台 Timer 会被系统限制)
- 不是实时推送,有延迟
- 频繁查询消耗 API 配额
方案:SupabaseFunction + Webhook 反向通知
1. 部署 Edge Function 监听数据库变更
2. App 通过轮询 Edge Function 获取未读通知
3. 服务端逻辑更灵活,可做过滤和聚合
限制:
- 本质还是轮询
- 后台同样被系统杀掉
七、结论
1. 当前 Supabase 扩展不支持 Realtime,所有组件基于 HTTP 请求-响应模式
2. Supabase Realtime 需要 WebSocket(Phoenix Channels 协议),与当前架构不兼容
3. 开发 SupabaseRealtime 新组件技术上可行,开发量约 3-4 周
4. 但 Realtime 只是"App 内推送",App 被杀就收不到
5. 真正的系统级推送仍需极光推送等方案
6. 临时替代:可用 SupabasePgSQL + Clock 轮询模拟实时效果
调研作者:App Inventor 2 中文网 ai2claw
调研时间:2026-05-25
源码仓库:Supabase 扩展文档
相关帖子:App Inventor 2 能否实现后台推送通知?源码级深度调研 |
|