Reputation: 127
According to this document, Supabase Realtime uses WebSocket to publish new events to the clients. However, is it possible to not use the Supabase JS SDK to subscribe to a channel for DB changes, say by using the WebSocket
object available in the browsers (or any other 3rd party WebSocket libraries such as socket.io)?
Here is how I tried to connect to my Supabase hosted project url using WebSocket
in order to listen to the new events. In this case, I want to listen to INSERT
event of a table.
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);
};
Note: I used the anon
API key in my Supabase hosted project.
However, it never received any event from my Supabase hosted project when I inserted new rows to the table.
The same would have worked
supabase
.channel('mychannel')
.on('postgres_changes', { event: '*', schema: 'public', table: 'MyTable' }, payload => {
console.log('Change received!', payload)
})
.subscribe()
How do I make it work? Or is it even possible?
Upvotes: 1
Views: 1020
Reputation: 127
I figured it out finally. I created another web client which uses the Supabase JS client SDK and inspected the WebSocket network packets in Chrome Developer Tools. After a wss
connection has been successfully established with the server (i.e. Supabase hosted project), the client needs to send the following messages to subscribe to the events and also regular heartbeats to keep the connection alive.
// to keep track of the id of each message sent to the server
let sentRef = 1;
// connect to wss
var ws = new WebSocket("wss://[project-ref].supabase.co/realtime/v1/websocket?apikey=[anon-token]&vsn=1.0.0");
// upon successful connection to wss
ws.onopen = function () {
console.log('socket connection opened properly');
// send 1st message to server to subscribe to events of DB changes
ws.send(JSON.stringify({"topic":"realtime:[channel-name]","event":"phx_join","payload":{"config":{"broadcast":{"ack":false,"self":false},"presence":{"key":""},"postgres_changes":[{"event":"*","schema":"public","table":"MyTable"}]},"access_token":"[anon-token]"},"ref":sentRef.toString(),"join_ref":"1"}));
sentRef++;
// send access token (anon key)
ws.send(JSON.stringify({"topic":"realtime:[channel-name]","event":"access_token","payload":{"access_token":"[anon-token]"},"ref":sentRef.toString(),"join_ref":"1"}));
sentRef++;
};
// parse the message received from server (DB changes)
ws.onmessage = function (evt) {
console.log("Message received = " + evt.data);
};
// need to keep the ws connection alive by sending a "heartbeat" every 30 seconds
setInterval(() => {
ws.send(JSON.stringify({"topic":"phoenix","event":"heartbeat","payload":{},"ref":sentRef.toString()}));
}, 30000)
Upvotes: 1