fix(webapp): keep device presence alive via heartbeats
This commit is contained in:
@@ -72,6 +72,7 @@ const DEFAULT_CAMERA_CONSTRAINTS = {
|
||||
height: { ideal: 360, max: 540 },
|
||||
frameRate: { ideal: 15, max: 24 }
|
||||
};
|
||||
const SOCKET_HEARTBEAT_INTERVAL_MS = 10_000;
|
||||
|
||||
const rtcConfig = {
|
||||
iceServers: [{ urls: 'stun:stun.l.google.com:19302' }]
|
||||
@@ -81,6 +82,7 @@ let initialized = false;
|
||||
let initPromise = null;
|
||||
let socket = null;
|
||||
let pollInterval = null;
|
||||
let socketHeartbeatInterval = null;
|
||||
let localCameraStream = null;
|
||||
let activeMediaRecorder = null;
|
||||
let activeRecordingChunks = [];
|
||||
@@ -1414,10 +1416,34 @@ const handleCameraStreamRequest = async ({ streamId, requesterDeviceId }) => {
|
||||
addActivity('Stream', 'Accepted stream request and started WebRTC offer');
|
||||
};
|
||||
|
||||
const stopSocketHeartbeat = () => {
|
||||
if (socketHeartbeatInterval) {
|
||||
clearInterval(socketHeartbeatInterval);
|
||||
socketHeartbeatInterval = null;
|
||||
}
|
||||
};
|
||||
|
||||
const emitSocketHeartbeat = () => {
|
||||
if (!socket?.connected) {
|
||||
return;
|
||||
}
|
||||
|
||||
socket.emit('heartbeat');
|
||||
};
|
||||
|
||||
const startSocketHeartbeat = () => {
|
||||
stopSocketHeartbeat();
|
||||
emitSocketHeartbeat();
|
||||
socketHeartbeatInterval = setInterval(() => {
|
||||
emitSocketHeartbeat();
|
||||
}, SOCKET_HEARTBEAT_INTERVAL_MS);
|
||||
};
|
||||
|
||||
const connectSocket = () => {
|
||||
const { deviceToken } = getAppState();
|
||||
if (!deviceToken) return;
|
||||
|
||||
stopSocketHeartbeat();
|
||||
if (socket) socket.disconnect();
|
||||
socket = io(getBackendUrl(), {
|
||||
auth: { token: deviceToken },
|
||||
@@ -1425,6 +1451,7 @@ const connectSocket = () => {
|
||||
});
|
||||
|
||||
socket.on('connect', () => {
|
||||
startSocketHeartbeat();
|
||||
setAppState({ socketConnected: true });
|
||||
addActivity('System', 'Connected to realtime server');
|
||||
if (getAppState().device?.role === 'camera') {
|
||||
@@ -1434,6 +1461,7 @@ const connectSocket = () => {
|
||||
});
|
||||
|
||||
socket.on('disconnect', () => {
|
||||
stopSocketHeartbeat();
|
||||
setAppState({ socketConnected: false });
|
||||
void stopLocalRecording();
|
||||
teardownPeerConnection();
|
||||
@@ -1443,6 +1471,7 @@ const connectSocket = () => {
|
||||
|
||||
socket.on('connect_error', (error) => {
|
||||
const message = error?.message || 'Realtime connection failed';
|
||||
stopSocketHeartbeat();
|
||||
setAppState({ socketConnected: false });
|
||||
addActivity('System', `Realtime connection failed: ${message}`);
|
||||
|
||||
@@ -1675,6 +1704,7 @@ const startPolling = () => {
|
||||
|
||||
const cleanupConnectionState = async () => {
|
||||
stopPolling();
|
||||
stopSocketHeartbeat();
|
||||
await stopLocalRecording();
|
||||
teardownPeerConnection();
|
||||
stopCameraPreview();
|
||||
|
||||
Reference in New Issue
Block a user