mirror of
https://github.com/openclaw/openclaw.git
synced 2026-02-09 05:19:32 +08:00
iOS: centralize gateway connect config
This commit is contained in:
27
apps/ios/Sources/Gateway/GatewayConnectConfig.swift
Normal file
27
apps/ios/Sources/Gateway/GatewayConnectConfig.swift
Normal file
@@ -0,0 +1,27 @@
|
||||
import Foundation
|
||||
import OpenClawKit
|
||||
|
||||
/// Single source of truth for "how we connect" to the current gateway.
|
||||
///
|
||||
/// The iOS app maintains two WebSocket sessions to the same gateway:
|
||||
/// - a `role=node` session for device capabilities (`node.invoke.*`)
|
||||
/// - a `role=operator` session for chat/talk/config (`chat.*`, `talk.*`, etc.)
|
||||
///
|
||||
/// Both sessions should derive all connection inputs from this config so we
|
||||
/// don't accidentally persist gateway-scoped state under different keys.
|
||||
struct GatewayConnectConfig: Sendable {
|
||||
let url: URL
|
||||
let stableID: String
|
||||
let tls: GatewayTLSParams?
|
||||
let token: String?
|
||||
let password: String?
|
||||
let nodeOptions: GatewayConnectOptions
|
||||
|
||||
/// Stable, non-empty identifier used for gateway-scoped persistence keys.
|
||||
/// If the caller doesn't provide a stableID, fall back to URL identity.
|
||||
var effectiveStableID: String {
|
||||
let trimmed = self.stableID.trimmingCharacters(in: .whitespacesAndNewlines)
|
||||
if trimmed.isEmpty { return self.url.absoluteString }
|
||||
return trimmed
|
||||
}
|
||||
}
|
||||
@@ -291,7 +291,8 @@ final class GatewayConnectionController {
|
||||
private func attemptAutoReconnectIfNeeded() {
|
||||
guard let appModel = self.appModel else { return }
|
||||
guard appModel.gatewayAutoReconnectEnabled else { return }
|
||||
guard appModel.gatewayServerName == nil else { return }
|
||||
// Avoid starting duplicate connect loops while a prior config is active.
|
||||
guard appModel.activeGatewayConnectConfig == nil else { return }
|
||||
guard UserDefaults.standard.bool(forKey: "gateway.autoconnect") else { return }
|
||||
self.didAutoConnect = false
|
||||
self.maybeAutoConnect()
|
||||
@@ -327,13 +328,14 @@ final class GatewayConnectionController {
|
||||
await MainActor.run {
|
||||
appModel.gatewayStatusText = "Connecting…"
|
||||
}
|
||||
appModel.connectToGateway(
|
||||
let cfg = GatewayConnectConfig(
|
||||
url: url,
|
||||
gatewayStableID: gatewayStableID,
|
||||
stableID: gatewayStableID,
|
||||
tls: tls,
|
||||
token: token,
|
||||
password: password,
|
||||
connectOptions: connectOptions)
|
||||
nodeOptions: connectOptions)
|
||||
appModel.applyGatewayConnectConfig(cfg)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -116,6 +116,7 @@ final class NodeAppModel {
|
||||
private var operatorConnected = false
|
||||
var gatewaySession: GatewayNodeSession { self.nodeGateway }
|
||||
var operatorSession: GatewayNodeSession { self.operatorGateway }
|
||||
private(set) var activeGatewayConnectConfig: GatewayConnectConfig?
|
||||
|
||||
var cameraHUDText: String?
|
||||
var cameraHUDKind: CameraHUDKind?
|
||||
@@ -1465,6 +1466,13 @@ extension NodeAppModel {
|
||||
let effectiveStableID = stableID.isEmpty ? url.absoluteString : stableID
|
||||
let sessionBox = tls.map { WebSocketSessionBox(session: GatewayTLSPinningSession(params: $0)) }
|
||||
|
||||
self.activeGatewayConnectConfig = GatewayConnectConfig(
|
||||
url: url,
|
||||
stableID: stableID,
|
||||
tls: tls,
|
||||
token: token,
|
||||
password: password,
|
||||
nodeOptions: connectOptions)
|
||||
self.prepareForGatewayConnect(url: url, stableID: effectiveStableID)
|
||||
self.startOperatorGatewayLoop(
|
||||
url: url,
|
||||
@@ -1482,6 +1490,20 @@ extension NodeAppModel {
|
||||
sessionBox: sessionBox)
|
||||
}
|
||||
|
||||
/// Preferred entry-point: apply a single config object and start both sessions.
|
||||
func applyGatewayConnectConfig(_ cfg: GatewayConnectConfig) {
|
||||
self.activeGatewayConnectConfig = cfg
|
||||
self.connectToGateway(
|
||||
url: cfg.url,
|
||||
// Preserve the caller-provided stableID (may be empty) and let connectToGateway
|
||||
// derive the effective stable id consistently for persistence keys.
|
||||
gatewayStableID: cfg.stableID,
|
||||
tls: cfg.tls,
|
||||
token: cfg.token,
|
||||
password: cfg.password,
|
||||
connectOptions: cfg.nodeOptions)
|
||||
}
|
||||
|
||||
func disconnectGateway() {
|
||||
self.gatewayAutoReconnectEnabled = false
|
||||
self.nodeGatewayTask?.cancel()
|
||||
@@ -1499,6 +1521,7 @@ extension NodeAppModel {
|
||||
self.gatewayServerName = nil
|
||||
self.gatewayRemoteAddress = nil
|
||||
self.connectedGatewayID = nil
|
||||
self.activeGatewayConnectConfig = nil
|
||||
self.gatewayConnected = false
|
||||
self.operatorConnected = false
|
||||
self.talkMode.updateGatewayConnected(false)
|
||||
|
||||
Reference in New Issue
Block a user