You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何不使用Supabase JS SDK,通过原生WebSocket监听数据库变更?

问题:不借助Supabase JS SDK,用原生WebSocket订阅数据库变更通道可行吗?

根据Supabase Realtime文档,它通过WebSocket向客户端推送新事件,但能否不依赖官方JS SDK,直接用浏览器原生WebSocket对象或第三方WebSocket库(比如socket.io)订阅数据库变更通道?

我尝试用以下原生WebSocket代码连接Supabase托管项目,监听表的INSERT事件:

var ws = new WebSocket("wss://[project-ref].supabase.co/realtime/v1/websocket?apikey=[anon-token]&log_level=info&vsn=1.0.0&schema=public&table=MyTable&event=*&channel=mychannel");
ws.onopen = function () {
    console.log('socket connection opened properly');
    ws.send("Hello World"); // send a message
    console.log('message sent');
};

ws.onmessage = function (evt) {
    console.log("Message received = " + evt.data);
};

注:我使用了Supabase托管项目中的anon API密钥。

但向表中插入新行时,从未收到Supabase返回的事件。而使用Supabase JS SDK的以下代码却能正常工作:

supabase
.channel('mychannel')
.on('postgres_changes', { event: '*', schema: 'public', table: 'MyTable' }, payload => {
    console.log('Change received!', payload)
})
.subscribe()

请问如何让原生WebSocket方案生效?或者该方案是否可行?


解答

完全可以用原生WebSocket实现,你的问题出在没有遵循Supabase Realtime的WebSocket协议规范——它不是简单通过URL参数完成订阅,而是需要在连接建立后发送特定格式的JSON消息,完成通道订阅、鉴权等流程。

核心问题分析

你当前的代码仅建立了WebSocket连接,发送的"Hello World"不符合Supabase Realtime基于Phoenix Channels协议的消息格式,服务端无法识别你的订阅请求,自然不会推送事件。

修正后的原生WebSocket实现步骤

  1. 简化连接URL:只保留必要参数(apikey、vsn),schema、table、event等订阅参数不需要放在URL里。
  2. 发送标准化订阅消息:连接打开后,发送phx_join类型的JSON消息,携带订阅配置与鉴权信息。
  3. 解析服务端响应:监听并解析服务端返回的JSON消息,筛选出postgres_changes类型的变更事件。

修正后的代码示例:

const projectRef = "[你的项目Ref]";
const anonKey = "[你的anon API密钥]";
// 使用2.0.0版本的协议,兼容性更好
const wsUrl = `wss://${projectRef}.supabase.co/realtime/v1/websocket?apikey=${anonKey}&vsn=2.0.0`;

const ws = new WebSocket(wsUrl);

ws.onopen = () => {
    console.log("WebSocket连接已建立");
    // 发送符合Phoenix Channels协议的订阅请求
    const joinMsg = JSON.stringify({
        topic: "realtime:public:MyTable", // 格式:realtime:[schema名称]:[表名称]
        event: "phx_join",
        payload: {
            config: {
                broadcast: { ack: false },
                presence: { key: "" },
                filter: { event: "*" } // 指定监听所有事件,可改为INSERT/UPDATE/DELETE
            }
        },
        ref: "1" // 唯一消息标识,可自定义任意字符串
    });
    ws.send(joinMsg);
    console.log("订阅请求已发送");
};

ws.onmessage = (evt) => {
    const data = JSON.parse(evt.data);
    console.log("收到消息:", data);
    
    // 捕获数据库变更事件
    if (data.event === "postgres_changes") {
        console.log("数据库变更详情:", data.payload);
    }
};

ws.onerror = (err) => {
    console.error("WebSocket错误:", err);
};

ws.onclose = () => {
    console.log("WebSocket连接已关闭");
};

关键细节说明

  • Topic格式:必须严格遵循realtime:[schema]:[table]的结构,比如监听public schema下的MyTable,topic就是realtime:public:MyTable。
  • 消息结构:所有交互消息都必须是JSON格式,包含四个必填字段:
    • topic:指定要订阅的通道主题
    • event:操作类型,订阅用phx_join,取消订阅用phx_leave
    • payload:包含订阅配置(如监听事件类型)
    • ref:唯一消息标识,用于匹配请求与响应
  • 协议版本:建议使用2.0.0,避免与当前Supabase Realtime版本不兼容。

验证方式

运行修正后的代码,向MyTable插入新数据,控制台会输出postgres_changes类型的消息,包含变更的完整数据。


内容的提问来源于stack exchange,提问作者Got Hima

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.03 21:46:18