Skip to content

Conversation

@anivar
Copy link
Contributor

@anivar anivar commented Sep 24, 2025

This PR addresses several long-standing user requests for better WebSocket connection control in the GraphQL API client. Users have reported issues with WebSocket connections not automatically reconnecting after network interruptions and lacking visibility into connection health status ( Fixes #9749, #4459, #5403, #7057).

The implementation enhances the existing AWSWebSocketProvider class with four new methods that leverage the existing ConnectionStateMonitor infrastructure and keep-alive tracking. These methods provide both real-time health monitoring and manual connection control that users have been requesting.

Enhanced WebSocket Provider Methods

  • getConnectionHealth() - Returns current health state using in-memory keep-alive tracking
  • getPersistentConnectionHealth() - Returns health state with cross-session persistence via AsyncStorage/localStorage
  • isConnected() - Checks if WebSocket.readyState === OPEN for immediate connection status
  • reconnect()/disconnect() - Manual connection control for user-triggered reconnection scenarios

Technical Implementation

The health monitoring uses the existing 65-second keep-alive threshold (DEFAULT_KEEP_ALIVE_ALERT_TIMEOUT) already established in the AppSync WebSocket protocol. A WebSocket is considered healthy when three conditions are met: connection state is Connected, a keep-alive was received within 65 seconds, and the underlying WebSocket readyState is OPEN.

For persistence, the implementation uses a platform-safe approach with AsyncStorage for React Native and localStorage fallback for web platforms. Keep-alive timestamps are stored at 'AWS_AMPLIFY_LAST_KEEP_ALIVE' to avoid key collisions. When storage is unavailable, the feature gracefully degrades to in-memory tracking only.

All changes are backward compatible with no breaking changes to existing functionality.

Copy link
Member

@bobbor bobbor left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for opening the PR.
Please take a look at the comments

import { awsRealTimeHeaderBasedAuth } from './authHeaders';

// Platform-safe AsyncStorage import
let AsyncStorage: any;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we have the KeyValueStorageInterface.

It can be (partially) used as a type here. and would be better than any

this.connectionState === ConnectionState.Connected &&
this.keepAliveTimestamp &&
timeSinceLastKeepAlive !== undefined &&
timeSinceLastKeepAlive < 65000; // 65 second threshold
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this can be shortened:

const isHealthy =
			this.connectionState === ConnectionState.Connected &&
			timeSinceLastKeepAlive < 65000; // 65 second threshold

// Use the more recent timestamp (in-memory vs persistent)
const lastKeepAliveTime =
Math.max(this.keepAliveTimestamp || 0, persistentKeepAliveTime || 0) ||
undefined;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why the undefined?
why not have lastKeepAliveTime be 0?

this simplifies timeSinceLastKeepAlive and isHealthy, too

@anivar anivar force-pushed the feat/websocket-health-monitoring branch from 1eb4414 to 044fc3c Compare October 31, 2025 13:06
…ction

- Add getConnectionHealth() method for current connection state
- Add getPersistentConnectionHealth() for cross-session health tracking
- Add isConnected() for quick connection status check
- Add reconnect() for manual WebSocket reconnection
- Implement persistent keep-alive tracking using AsyncStorage/localStorage
- Use 65-second threshold for health monitoring
- Track keep-alive timestamps for connection health assessment

Fixes aws-amplify#9749, aws-amplify#4459, aws-amplify#5403, aws-amplify#7057
@anivar anivar force-pushed the feat/websocket-health-monitoring branch from d1cf448 to 9c832cd Compare October 31, 2025 13:35
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Unable to reconnect AppSync after connection interruption (web) or app going into background (ios/ android)

2 participants