Session Lifecycle
To ensure reliability for users on Revolt, clients should implement the following rigid specification for maintaing a session. At a high-level, it should be implemented as a state machine.
flowchart TD subgraph LOGGED_IN[Logged In - Display Client UI] CONNECTED CONNECTING RECONNECTING DISCONNECTED OFFLINE ... end subgraph LOGGED_OUT[Logged Out - Display Auth Flow or Loading Indicator] READY LOGGING_IN ONBOARDING DISPOSE ERROR end READY -->|LOGIN_UNCACHED| LOGGING_IN READY -->|LOGIN_CACHED| CONNECTING LOGGING_IN -->|NO_USER| ONBOARDING LOGGING_IN -->|PERMANENT_FAILURE| ERROR LOGGING_IN -->|TEMPORARY_FAILURE| ERROR ONBOARDING -->|CANCEL| DISPOSE DISPOSE -->|READY| READY ERROR -->|DISMISS| DISPOSE LOGGING_IN -->|SOCKET_CONNECTED| CONNECTED RECONNECTING -->|SOCKET_CONNECTED| CONNECTED CONNECTING -->|SOCKET_CONNECTED| CONNECTED ONBOARDING -->|USER_CREATED| LOGGING_IN CONNECTED -->|TEMPORARY_FAILURE| DISCONNECTED DISCONNECTED -->|RETRY| RECONNECTING DISCONNECTED -->|DEVICE_OFFLINE| OFFLINE RECONNECTING -->|TEMPORARY_FAILURE| DISCONNECTED CONNECTING -->|TEMPORARY_FAILURE| DISCONNECTED CONNECTING -->|PERMANENT_FAILURE| ERROR RECONNECTING -->|PERMANENT_FAILURE| ERROR OFFLINE -->|DEVICE_ONLINE| RECONNECTING ... -->|LOGOUT| DISPOSE
Implementation Details
The table below describes how each node should behave.
- All nodes SHOULD have corresponding visual feedback.
- Nodes MAY have effects on entry.
- You SHOULD keep track of additional state such as:
- Number of connection failures
Node | User Interface | Logic |
---|---|---|
READY | Show login interface | May transition out by external source. |
LOGGING_IN | Show loading indicator | On entry, try to authenticate the user. |
ONBOARDING | Show username selection | May transition out by external source. |
ERROR | Show the permanent error with option to dismiss it | May transition out by external source. |
DISPOSE | Show loading indicator | Dispose current client and create a new one. |
CONNECTING | Show client UI with banner "Connecting" | On entry, try to connect socket. |
CONNECTED | Show client UI | May transition out by external source. Set connection failures to . |
DISCONNECTED | Show client UI with banner "Disconnected" | May transition out by external source. Increment connection failures by . If the device is offline, trigger transition to OFFLINE. On entry, set a timer to retry†. On exit, cancel timer. |
RECONNECTING | Show client UI with banner "Reconnecting" | On entry, invalidate cached data (message history, members list) and try to connect socket. |
OFFLINE | Show client UI with banner "Device offline" | May transition out by external source. |
† Please use the formula for the delay where is failure count.
// JavaScript implementation
let retryIn =
(Math.pow(2, connectionFailureCount) - 1) * (0.8 + Math.random() * 0.4);
let retryInMs = retryIn * 1e3;
setTimeout(() => reconnect(), retryInMs);
The following listeners need to be registered that emit the given transitions:
Listener | Transition |
---|---|
Connected to Revolt (and initial data loaded) | SOCKET_CONNECTED |
Connection to Revolt dropped | SOCKET_DROPPED |
Received logout event from socket | LOGOUT |
Connection failed | TEMPORARY_FAILURE |
Connection failed (session invalid) | PERMANENT_FAILURE |
Device has gone online | DEVICE_ONLINE |
Socket Details
When implementing your WebSocket connection, you should also implement the following:
- A heartbeat mechanism that sends the Ping event every 30 seconds, and disconnects if a Pong event is not received within 10 seconds.
- A connection timeout mechanism that drops the WebSocket connection if no message is received within 10 seconds of initiating the connection.
User Experience Considerations
- While not strictly relevant to session lifecycle, if you encounter BlockedByShield during login, you should provide a link to the relevant support article.
- Upon encountering a permanent error (session invalid), you should use the known user information to fetch their current flags. This way the message can be tailored to display if: they have been logged out, they disabled their account, their account has been suspended, or their account has been banned.
- When a logout event is received externally, show some sort of indicator that they have been logged out beyond just kicking them to the login screen.
If the connection failure count reaches or more, query the health service for any outage information.This point is WIP, need considerations about increasing polling rate while connection failures are high, etc.