@@ -49,7 +49,17 @@ type RealtimeRequestAuthenticate = {
4949
5050type Realtime = {
5151 socket?: WebSocket;
52+
53+ /**
54+ * Timeout for reconnect operations.
55+ */
5256 timeout?: number;
57+
58+ /**
59+ * Heartbeat interval for the realtime connection.
60+ */
61+ heartbeat?: number;
62+
5363 url?: string;
5464 lastMessage?: RealtimeResponse;
5565 channels: Set<string >;
@@ -63,6 +73,7 @@ type Realtime = {
6373 getTimeout: () => number;
6474 connect: () => void;
6575 createSocket: () => void;
76+ createHeartbeat: () => void;
6677 cleanUp: (channels: string[]) => void;
6778 onMessage: (event: MessageEvent) => void;
6879}
@@ -174,6 +185,7 @@ class Client {
174185 private realtime: Realtime = {
175186 socket: undefined,
176187 timeout: undefined,
188+ heartbeat: undefined,
177189 url: '',
178190 channels: new Set(),
179191 subscriptions: new Map(),
@@ -199,6 +211,17 @@ class Client {
199211 return 60_000;
200212 }
201213 },
214+ createHeartbeat: () => {
215+ if (this.realtime.heartbeat) {
216+ clearTimeout(this.realtime.heartbeat);
217+ }
218+
219+ this.realtime.heartbeat = window?.setInterval(() => {
220+ this.realtime.socket?.send(JSON.stringify({
221+ type: 'ping'
222+ }));
223+ }, 20_000);
224+ },
202225 createSocket: () => {
203226 if (this.realtime.channels.size < 1) {
204227 this.realtime.reconnect = false;
@@ -237,6 +260,7 @@ class Client {
237260 this.realtime.socket.addEventListener('message', this.realtime.onMessage);
238261 this.realtime.socket.addEventListener('open', _event => {
239262 this.realtime.reconnectAttempts = 0;
263+ this.realtime.createHeartbeat();
240264 });
241265 this.realtime.socket.addEventListener('close', event => {
242266 if (
0 commit comments