Skip to content

Commit 570ee57

Browse files
feat: implement heartbeat
1 parent 52ab35c commit 570ee57

File tree

2 files changed

+35
-8
lines changed

2 files changed

+35
-8
lines changed

.phpactor.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
{
2+
"$schema": "/phpactor.schema.json",
3+
"php_code_sniffer.enabled": false
4+
}

templates/web/src/client.ts.twig

Lines changed: 31 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,9 @@ type Headers = {
1919
*/
2020
type RealtimeResponse = {
2121
/**
22-
* Type of the response: 'error', 'event', 'connected', or 'response'.
22+
* Type of the response: 'error', 'event', 'connected', 'pong', or 'response'.
2323
*/
24-
type: 'error' | 'event' | 'connected' | 'response';
24+
type: 'error' | 'event' | 'connected' | 'response' | 'pong';
2525

2626
/**
2727
* Data associated with the response based on the response type.
@@ -139,9 +139,14 @@ type Realtime = {
139139
socket?: WebSocket;
140140

141141
/**
142-
* Timeout duration for communication operations.
142+
* Timeout for reconnect operations.
143143
*/
144-
timeout?: number;
144+
timeout?: ReturnType<typeof setTimeout>;
145+
146+
/**
147+
* Heartbeat interval for the realtime connection.
148+
*/
149+
heartbeat?: ReturnType<typeof setTimeout>;
145150

146151
/**
147152
* URL for establishing the WebSocket connection.
@@ -196,6 +201,11 @@ type Realtime = {
196201
*/
197202
createSocket: () => void;
198203

204+
/**
205+
* Function to create a new heartbeat interval.
206+
*/
207+
createHeartbeat: () => void;
208+
199209
/**
200210
* Function to clean up resources associated with specified channels.
201211
*
@@ -359,6 +369,7 @@ class Client {
359369
private realtime: Realtime = {
360370
socket: undefined,
361371
timeout: undefined,
372+
heartbeat: undefined,
362373
url: '',
363374
channels: new Set(),
364375
subscriptions: new Map(),
@@ -384,6 +395,17 @@ class Client {
384395
return 60_000;
385396
}
386397
},
398+
createHeartbeat: () => {
399+
if (this.realtime.heartbeat) {
400+
clearTimeout(this.realtime.heartbeat);
401+
}
402+
403+
this.realtime.heartbeat = window?.setInterval(() => {
404+
this.realtime.socket?.send(JSON.stringify({
405+
type: 'ping'
406+
}));
407+
}, 20_000);
408+
},
387409
createSocket: () => {
388410
if (this.realtime.channels.size < 1) {
389411
this.realtime.reconnect = false;
@@ -417,6 +439,7 @@ class Client {
417439
this.realtime.socket.addEventListener('message', this.realtime.onMessage);
418440
this.realtime.socket.addEventListener('open', _event => {
419441
this.realtime.reconnectAttempts = 0;
442+
this.realtime.createHeartbeat();
420443
});
421444
this.realtime.socket.addEventListener('close', event => {
422445
if (
@@ -497,10 +520,10 @@ class Client {
497520

498521
/**
499522
* Subscribes to {{spec.title | caseUcfirst}} events and passes you the payload in realtime.
500-
*
501-
* @param {string|string[]} channels
523+
*
524+
* @param {string|string[]} channels
502525
* Channel to subscribe - pass a single channel as a string or multiple with an array of strings.
503-
*
526+
*
504527
* Possible channels are:
505528
* - account
506529
* - collections
@@ -628,7 +651,7 @@ class Client {
628651

629652
async redirect(method: string, url: URL, headers: Headers = {}, params: Payload = {}): Promise<string> {
630653
const { uri, options } = this.prepareRequest(method, url, headers, params);
631-
654+
632655
const response = await fetch(uri, {
633656
...options,
634657
redirect: 'manual'

0 commit comments

Comments
 (0)