Skip to content

Commit

Permalink
[lib] implement socket Heartbeats with Tunnelbroker
Browse files Browse the repository at this point in the history
Summary:
Implements protocol described in D9630.

Depends on D9631

Test Plan:
1. Test if client properly exchange `Heartbeats`
2. Test if timeout works

Reviewers: michal, bartek, varun

Reviewed By: michal

Subscribers: ashoat, tomek, wyilio

Differential Revision: https://phab.comm.dev/D9632
  • Loading branch information
xsanm committed Nov 6, 2023
1 parent 426f916 commit 6ad8d2f
Showing 1 changed file with 26 additions and 1 deletion.
27 changes: 26 additions & 1 deletion lib/tunnelbroker/tunnelbroker-context.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ import * as React from 'react';
import uuid from 'uuid';

import { tunnnelbrokerURL } from '../facts/tunnelbroker.js';
import { tunnelbrokerHeartbeatTimeout } from '../shared/timeouts.js';
import type { Heartbeat } from '../types/tunnelbroker/heartbeat-types.js';
import type { MessageReceiveConfirmation } from '../types/tunnelbroker/message-receive-confirmation-types.js';
import type { MessageSentStatus } from '../types/tunnelbroker/message-to-device-request-status-types.js';
import type { MessageToDeviceRequest } from '../types/tunnelbroker/message-to-device-request-types.js';
Expand Down Expand Up @@ -51,6 +53,22 @@ function TunnelbrokerProvider(props: Props): React.Node {
const listeners = React.useRef<Set<TunnelbrokerSocketListener>>(new Set());
const socket = React.useRef<?WebSocket>(null);
const promises = React.useRef<Promises>({});
const heartbeatTimeoutID = React.useRef();

const stopHeartbeatTimeout = React.useCallback(() => {
if (heartbeatTimeoutID.current) {
clearTimeout(heartbeatTimeoutID.current);
heartbeatTimeoutID.current = null;
}
}, []);

const resetHeartbeatTimeout = React.useCallback(() => {
stopHeartbeatTimeout();
heartbeatTimeoutID.current = setTimeout(() => {
socket.current?.close();
setConnected(false);
}, tunnelbrokerHeartbeatTimeout);
}, [stopHeartbeatTimeout]);

React.useEffect(() => {
if (connected || !initMessage) {
Expand Down Expand Up @@ -89,6 +107,8 @@ function TunnelbrokerProvider(props: Props): React.Node {
}
const message: TunnelbrokerMessage = rawMessage;

resetHeartbeatTimeout();

for (const listener of listeners.current) {
listener(message);
}
Expand Down Expand Up @@ -134,11 +154,16 @@ function TunnelbrokerProvider(props: Props): React.Node {
console.log('Tunnelbroker recorded InvalidRequest');
}
}
} else if (message.type === tunnelbrokerMessageTypes.HEARTBEAT) {
const heartbeat: Heartbeat = {
type: tunnelbrokerMessageTypes.HEARTBEAT,
};
socket.current?.send(JSON.stringify(heartbeat));
}
};

socket.current = tunnelbrokerSocket;
}, [connected, initMessage]);
}, [connected, initMessage, resetHeartbeatTimeout, stopHeartbeatTimeout]);

const sendMessage: (message: ClientMessageToDevice) => Promise<void> =
React.useCallback(
Expand Down

0 comments on commit 6ad8d2f

Please sign in to comment.