MAX: When the Carrier Is Also a Service Account

OpenFlux’s MAX transport changes the carrier problem from “which document session can carry bytes?” to “which account, call, and signaling state can carry them?” This chapter traces that path and separates three things that are easy to conflate: the messaging service’s signaling channel, the WebRTC objects created around a call, and the code path that actually moves OpenFlux payloads. The comparison with Yandex is useful only when it exposes those different dependencies, not when it declares a universal winner.

Login, identity, and role determine the session

The MAX adapter begins with a service connection rather than a document URL. It creates a client for the messaging service, opens its WebSocket, and logs in with a supplied token. The client also maintains a service identity and keeps the messaging session alive. The token is therefore not an incidental setting; it is the credential that lets the carrier act as a particular account.

The two ends of an OpenFlux connection take different roles. In client mode, the adapter starts an outgoing call toward a configured user ID. In exit-node mode, it waits for an incoming call and prepares to accept it. The user ID identifies the peer that the client expects to reach; the token identifies the account making the service requests. Together they determine whether the call can be discovered and which service-side conversation carries the transport.

That role split is the MAX equivalent of Yandex’s document-session bootstrap, but it creates a different operational surface. A document URL can be replaced or made inaccessible. An account token can be revoked, exposed, restricted, or tied to activity that the provider evaluates independently of OpenFlux. The connection also depends on the other user ID and on the service’s call-discovery behavior. A byte-oriented Transport interface hides these identities from the tunnel, but the carrier cannot function without them.

After the messaging client discovers a call, the call handler opens another signaling WebSocket and processes service messages. It learns the conversation participants, obtains call parameters, and uses the supplied session information to construct a WebRTC peer connection. The receiver and caller do not enter the same sequence at the same moment: an incoming call must be noticed and accepted, while an outgoing call must be initiated and wait for the peer’s response. The role determines the first transition in the adapter’s state machine.

stateDiagram-v2 [*] --> LoggedOut LoggedOut --> LoggedIn: Connect and login with token LoggedIn --> Calling: Start outgoing call LoggedIn --> Waiting: Listen for incoming call Calling --> Signaling: Call parameters received Waiting --> Signaling: Incoming call accepted Signaling --> PeerReady: Peer connection created PeerReady --> Exchanging: Active payload path ready Exchanging --> Reconnecting: Signaling or call disconnects Reconnecting --> Calling: Recreate outgoing call Reconnecting --> Waiting: Recreate incoming listener Exchanging --> Stopping: Stop transport Reconnecting --> Stopping: Stop transport Stopping --> [*]

The state machine makes an important distinction visible: a successful login is not a usable packet path.