709e254c15
When a relay enters a long backoff (5 min, e.g. host unreachable or a server returned an HTTP error during handshake), the per-relay delayToConnectInSeconds blocks reconnect attempts for up to 5 minutes. Without a wakeup, nothing inside NostrClient revisits that relay until the next subscribe/count/publish. Add a keep-alive coroutine that calls reconnectIfNeedsTo(false) every 60s while the client is active. The per-relay backoff still gates the actual reconnect, so dead relays are not hammered, but a relay whose backoff window has elapsed is reconnected within ~60s of becoming eligible. The job lives in scope and is cancelled by close().