Guide: Handle discontinuity in Chat

Open in

When a client experiences a period of disconnection longer than the two-minute recovery window, or when Ably signals a loss of message continuity, your application may have missed messages. This is called a discontinuity. This guide explains how to detect and recover from discontinuities in Chat applications.

What causes discontinuity

Discontinuity occurs when the Ably SDK cannot guarantee that all messages have been delivered to the client. The most common causes are:

  • Network disconnection lasting longer than two minutes. Ably preserves connection state for up to two minutes. Beyond this window, Ably cannot guarantee message continuity.
  • Server-initiated continuity loss. Operational events such as cluster rebalancing may cause a partial loss of message continuity, even if the client remained connected.
  • Outbound rate limits exceeded. If a connection's outbound message rate exceeds the per-connection limit, messages may be dropped, resulting in a loss of continuity.
  • Client app backgrounded for an extended period. Mobile apps suspended by the operating system may exceed the two-minute recovery window.

For disconnections shorter than two minutes, the SDK automatically resumes the connection and replays missed messages without any action from you.

Detect discontinuity

The Chat SDK provides an onDiscontinuity() handler at the room level. This is a Chat-specific mechanism, separate from the Pub/Sub resumed flag.

Register the handler when setting up your room:

1

2

3

4

5

6

7

const { off } = room.onDiscontinuity((reason) => {
  console.log('Discontinuity detected:', reason);
  recoverChatMessages(room);
});

// Clean up when done
off();

Recover missed messages

Use historyBeforeSubscribe() to retrieve messages from the point of re-subscription. This is preferred over messages.history() for discontinuity recovery because the attachment point changes after a resume, and historyBeforeSubscribe guarantees no gap between historical and live messages:

JavaScript

1

2

3

4

5

6

7

8

async function recoverChatMessages(room) {
  const history = await room.messages.historyBeforeSubscribe({ limit: 50 });

  // Refresh your message list with recovered messages
  for (const msg of history.items.reverse()) {
    appendMessageToUI(msg);
  }
}

Best practices

  • Set up the onDiscontinuity handler before subscribing to messages. This ensures you detect any continuity loss that occurs during the initial attachment.
  • Use historyBeforeSubscribe() for recovery. It is designed to work with the Chat discontinuity detection mechanism and guarantees no gap between historical and live messages.
  • The onDiscontinuity handler fires at the room level, covering messages, presence, reactions, and typing indicators. You do not need to register separate handlers for each Chat feature.
  • Decide how to present recovered messages to the user. Options include refreshing the message list, showing a "new messages" indicator, or displaying a notification that messages were recovered.