Realtime

Connected apps get live updates over one WebSocket. This page explains how that connection behaves. The exact channels, events and payloads are in the Realtime reference:

Realtime, push or webhook?

poolse tells the outside world about the same events in three ways. Each reaches a different place.

Realtime (WebSocket)Push notificationWebhook
ReachesYour app, while it is open and connectedThe user's phone, even when the app is closedYour backend
Sent bypoolse, to members of the conversationpoolse, through Apple (APNs) and Google (FCM)poolse, to your URL
AuthThe user's tokenYour push credentials in the dashboardYour webhook signing secret
Use it forUpdating the UI liveRinging phones, chat and missed-call notificationsYour own records, search, moderation, emails
Missed if offline?Yes: reload from REST on reconnectDelivered when the phone comes back, as Apple or Google decideNo: retried for up to about 15 hours

See Push notifications and Webhooks.

The connection

  • The SDK opens one WebSocket per client and puts every channel on it. Watching ten conversations still uses one socket.
  • It authenticates with the user's token, sent when the socket connects. A missing, expired, revoked or blocked user's token is refused, and the socket keeps retrying. Blocking a user, or revoking one of their tokens, closes the sockets they have open.
  • The protocol is Phoenix Channels. The SDK includes the client; you don't install anything else.
  • The socket opens lazily, the first time something subscribes to a channel, for example when a useMessages hook mounts.

There are two kinds of channel:

  • conversation:<id>: one per conversation the app is showing. Only members can join. A member who is removed has the channel closed at once, and the SDK does not rejoin it.
  • user:<id>: one per signed-in user, for events that aren't tied to the conversation on screen (a new conversation, a mention, a call that stopped ringing). A user can only join their own.

Connection status

The SDK reports one of these statuses (useRealtimeStatus() in React):

StatusMeans
idleNothing has subscribed yet, so no socket is open.
connectingOpening the socket.
connectedOpen and receiving events.
reconnectingThe connection dropped or failed; the SDK is retrying.
closedClosed on purpose (disconnect() or pause()).

Show a "reconnecting" banner on reconnecting. If the status stays at connecting / reconnecting, the usual cause is a token problem; see Troubleshooting.

Reconnects

When the connection drops, the SDK reconnects on its own, waiting a little longer each time (from 10 ms up to 5 seconds between tries), and rejoins every channel it had.

Events sent while the socket was down are not replayed. To catch up:

  • From 3.1, useMessages and useConversations reload from REST when the socket reconnects. Nothing to do if you use them.
  • If you use @poolse/sdk directly, refetch what you show when the status goes back to connected.

Backgrounding (mobile)

Phones suspend sockets in the background. From 3.1 the SDK has realtime.pause() and realtime.resume():

  • pause() closes the socket but keeps every channel handle and its listeners.
  • resume() gets a fresh token, reopens the socket and rejoins the channels. Hooks then reload from REST.

In React Native, mount useAppStateLifecycle() once inside the provider. It pauses when the app goes to the background and resumes when it is active again. While paused, push notifications cover new messages and calls.

Sending

Sends go over REST, not the socket. useMessages().send adds the message to the list at once with a client-generated id. When the REST response or the message:new event arrives with that id, it replaces the optimistic copy, so the message never shows twice. If the send fails, the optimistic message is removed and send throws, so you can show an error and let the user retry.

Typing indicators are the only thing the client sends over the socket.

What realtime does not do

  • No fallback to long polling or server-sent events. If WebSockets are blocked, REST still works but nothing updates live.
  • No replay of missed events (see Reconnects).
  • No "delivered" receipts. Read state is covered in Read receipts & unread.
Realtime · poolse docs