P2.1: Add GatewayConnector BackgroundService with WebSocket client

- GatewayConnector: BackgroundService maintaining persistent WebSocket connection
  to OpenClaw Gateway with Bearer token auth from backend env only
- IGatewayConnector: Interface exposing connection state, version info, health
- Exponential backoff reconnect: 1s initial, max 5min, with jitter
- Version pinning: RequiredVersion from config; fail-fast or warn on mismatch
- Pre-flight HTTP version check before WebSocket connect
- GatewayHealthController: GET /api/health/gateway with connection status
- GatewayConnectorOptions: Configurable via GatewayConnector config section
- Token never logged; read from Integrations:OpenClaw:Password/Token only
- 16 tests: options defaults, config binding, health endpoint responses,
  connection states, DI registration, routing attributes
This commit is contained in:
2026-07-13 14:13:39 +02:00
parent a55951f315
commit 6ba788bb6e
6 changed files with 925 additions and 0 deletions
+57
View File
@@ -0,0 +1,57 @@
using Nexus.Api.Models;
namespace Nexus.Api.Services;
/// <summary>
/// Maintains a persistent WebSocket connection to the OpenClaw Gateway
/// for real-time event streaming and health monitoring.
/// </summary>
public interface IGatewayConnector
{
/// <summary>
/// Current WebSocket connection state.
/// </summary>
GatewayConnectionState ConnectionState { get; }
/// <summary>
/// Gateway version reported at last connection.
/// </summary>
string? GatewayVersion { get; }
/// <summary>
/// Required version from configuration, or null when unpinned.
/// </summary>
string? RequiredVersion { get; }
/// <summary>
/// Timestamp of the last successful connection attempt.
/// </summary>
DateTimeOffset? LastConnectedAt { get; }
/// <summary>
/// Number of consecutive failed connection attempts.
/// </summary>
int ReconnectAttempts { get; }
/// <summary>
/// Detailed status message (e.g. error or version info).
/// </summary>
string? StatusMessage { get; }
}
/// <summary>
/// Represents the current connection state of the GatewayConnector.
/// </summary>
public enum GatewayConnectionState
{
/// <summary>Not yet attempted or initializing.</summary>
Initializing,
/// <summary>Connected and healthy.</summary>
Connected,
/// <summary>Disconnected, waiting for reconnect.</summary>
Disconnected,
/// <summary>Recoverable error, retrying.</summary>
Reconnecting,
/// <summary>Failed after maximum retries.</summary>
Failed
}