onSessionInvalidated

fun onSessionInvalidated(listener: () -> Unit): Closeable

Fires when the backend rejects this instance's credential with a 401 — the session ended somewhere this app cannot see, so the end user has to sign in again.

Fires at most once for this instance's credential, no matter how many requests 401 together or in sequence. clearSession does not fire it, and neither does a Portal built from a Client API Key: that key is custodian-owned and has no session to end.

The credential is set once at construction, so this instance stays spent. After the next sign-in, construct a new Portal on the new session and subscribe again.

The listener runs on the thread that detected the rejection — an OkHttp dispatcher, Dispatchers.IO, or the WebSocket's own scope — never on the main thread. Post to your own scope before touching UI. Keep it short: it runs inline with the failing request's bookkeeping.

private val sessionSubscription = portal.onSessionInvalidated {
lifecycleScope.launch { navigateToLogin() }
}

override fun onDestroy() {
sessionSubscription.close()
super.onDestroy()
}

Return

A handle that removes the listener. Close it when the subscriber goes away — until then the listener, and whatever it captures, stays reachable for as long as the session does. Closing twice, or from inside the listener, is safe.