CLEMA protocol

Connection Management

Keepalive

The server closes a WebSocket connection it has received nothing from for 120 seconds, announcing it with connection.closing and reason timeout. Connections through a transport adapter follow their own protocol's keepalive instead. Anything counts: a request, connection.ping or a WebSocket ping frame. A client with nothing to send sends one of the last two at least every 60 seconds. Native ping frames are the cheaper choice; browsers cannot send them and use connection.ping.

Ping

Checks the connection at application level and keeps it alive, for clients that cannot send WebSocket ping frames.

Request:

{"type": "connection.ping"}

Control reply:

{"type": "connection.pong"}

Disconnect

The client can send connection.close to gracefully close the session.

Request:

{"type": "connection.close"}

Response:

{"type": "connection.close", "ok": true}

After queuing this response, the server closes the underlying connection.

Server may also initiate disconnect:

{
  "type": "connection.closing",
  "data": {
    "reason": "timeout",
    "message": "No activity for 120 seconds"
  }
}

Reason values:

Passive Connections

A connection is active while somebody is looking at the client, and passive while the client works unseen — a page in a background tab, or an app syncing in the background after a push woke it. A passive connection:

A connection is active unless the client says otherwise; one through a transport adapter always is, since its protocol has no such notion. A background sync passes "active": false in connection.hello, so that it never counts as somebody looking, not even for a moment: the device keeps getting its pushes, and its user does not flash active. activity.set switches an open connection when the client comes to the foreground or leaves it:

{"id":"act-1","type":"activity.set","data":{"active":false}}
{"id":"act-1","type":"activity.set","ok":true}

Turning the user's last active connection passive sends contacts presence.updated with the user no longer active, once the grace has passed with nobody looking again, so that a switch between apps tells them nothing. Turning one active sends presence.updated at once. Neither changes whether the user is online, nor their chosen state and custom status.