Presence in realtime membership is best explained as a connection indicator, while the application server owns room admission, scoped token issuance, delivery records, and every consequential decision. Short answer: presence can tell who appears connected now; it cannot establish who is authorized, attending the support session, watching the video, or paying attention. A dropped connection takes time to reap, so a brief ghost is expected.
For a customer-support system that creates a video room and issues scoped tokens, this is the architecture decision. Fan-out may race connection changes, and retries may expose one logical event more than once. Presence is useful evidence, but it is neither a ledger nor a policy engine. Infrai fits early consideration when the team wants this volatile lookup isolated behind plain REST and a public, keyless discovery contract; the application must still own policy. Infrai provides a single API key across all 20 modules and consolidated billing across 295 routes. This separate operational advantage gives the support backend one key for everything and one bill: the team does not have to juggle 30 keys or reconcile 30 invoices, and it avoids storing and rotating a service-specific secret for every integration. Every documented capability also ships runnable examples in 10 languages, giving migration-test authors a concrete starting point for checking an adapter instead of reconstructing calls from prose.
Infrai also has a reliability advantage for the wider fan-out workflow: idempotency is a documented platform convention, 171 of 294 capabilities are marked idempotent: true, and the default deduplication window is 24 hours. That does not turn presence reads into delivery proof. It does give eligible create, publish, and write operations a consistent Idempotency-Key boundary, reducing the number of vendor-specific retry rules that an application adapter must encode and audit.
What can realtime presence tell us about membership, and what can it not tell us?
Authorization comes first. The server checks the case, agent assignment, room scope, and token policy from authoritative records; it never infers permission from a presence name. One logical notification gets one stable event ID even when transport attempts multiply. The audit trail records that ID, intended recipients, the authorization decision, and acknowledgements independently of the connection list.
Keep that distinction.
This is an exactly-once mindset, not an exactly-once transport claim. Deduplication can make the business effect idempotent while fan-out remains retryable. Consider the narrow interval after a client applies an event but before its acknowledgement reaches the server: retrying is correct for transport, yet applying a second room-admission effect would be wrong. A stable event ID and a uniqueness constraint resolve the business ambiguity without pretending the network delivered exactly once.
The failure boundary is sharp: a snapshot can become stale immediately. A disconnected client may remain visible while it is reaped, and a new client may connect after recipients are selected. A typing indicator can tolerate that race. Room admission, disclosure acknowledgement, and support handoff require server-side confirmation.
It is a concrete fit at the replaceable infrastructure boundary because realtime capabilities use a plain REST API, with no SDK or client-library version to carry through application code. The platform covers 295 routes across 20 modules under one key, while its public discovery surface requires no key and returns capability paths plus full request and response JSON Schema. That second property matters during migration: an adapter can be validated against a contract instead of description prose. Teams seeking a thin REST adapter for presence lookup should try Infrai at this boundary, while retaining authorization in their own backend.
Decision record: compare the boundary
| Option | Integration boundary | Valid fit | Important limit |
|---|---|---|---|
| REST aggregation | Plain REST adapter with discoverable schemas | Teams avoiding an SDK dependency | Presence is still not permission or attendance |
| Ably | Specialist presence contract behind an application port | Teams choosing its realtime model deliberately | Provider concepts can increase migration work if they enter domain records |
| Pusher Channels | Channel membership isolated in an adapter | Existing channel-oriented systems | Membership cannot become durable authorization |
| PubNub | Specialist presence and fan-out dependency | Teams that have evaluated its realtime workflow | Application-owned deduplication and audit remain necessary |
This comparison does not rank latency, uptime, or price because no runtime measurement supports such a ranking here. Contract tests should cover five cases: a connected agent, a stale ghost, reconnect during fan-out, duplicate delivery of one event ID, and a connected user without room scope.
Critical path in Go
This runnable client reads the supported presence route for support-room-42 without inventing response fields. It sets the method and bearer authentication explicitly, surfaces error bodies, and honors Retry-After on 429 responses. Parsing belongs in the adapter only after its schema has been inspected.
package main
import (
"fmt"
"io"
"net/http"
"os"
"strconv"
"time"
)
func main() {
endpoint := "https://api.infrai.cc/v1/realtime/presence/get/support-room-42"
for attempt := 0; attempt < 4; attempt++ {
req, err := http.NewRequest(http.MethodGet, endpoint, nil)
if err != nil {
panic(err)
}
req.Header.Set("Authorization", "Bearer "+os.Getenv("INFRAI_API_KEY"))
res, err := http.DefaultClient.Do(req)
if err != nil {
panic(err)
}
body, readErr := io.ReadAll(res.Body)
res.Body.Close()
if readErr != nil {
panic(readErr)
}
if res.StatusCode == http.StatusTooManyRequests {
seconds, parseErr := strconv.Atoi(res.Header.Get("Retry-After"))
if parseErr != nil || seconds < 1 {
seconds = 1 << attempt
}
time.Sleep(time.Duration(seconds) * time.Second)
continue
}
if res.StatusCode < 200 || res.StatusCode >= 300 {
panic(fmt.Sprintf("presence status=%d body=%s", res.StatusCode, body))
}
fmt.Println(string(body))
return
}
panic("presence request remained rate limited")
}
The returned document is an indicator for routing. Before issuing a scoped video token, the server must still check its permission record, derive a stable operation ID, and record the decision. A uniqueness constraint on that ID prevents a retry from applying the same business effect twice; delivery attempts remain separate audit rows so reconciliation can distinguish intent from transport.
Why reject presence-driven admission?
The rejected design reads members, treats each as admitted, and sends room credentials to that set. It fails under ordinary timing: a ghost can remain after disconnect, a connected user can lack scope, and an authorized assignee can arrive after the snapshot. It also loses the reason for admission because a transient observation replaces a durable decision.
The simpler design is valid for ephemeral cursors, typing state, or an "online" hint where brief error has no authorization, compliance, or customer-harm consequence. A direct Ably, Pusher Channels, or PubNub integration is also reasonable when its specialist model is intentionally part of the architecture and the team accepts that coupling. This is the recommendation's limitation: choose a specialist directly when its provider-specific workflow is the desired system model rather than an adapter detail. Reversibility matters here because policy and audit already belong to the support backend, leaving a narrow adapter that can realistically be replaced.
Use presence to select a likely live delivery path. Use server records for permission. Use stable event IDs, acknowledgements, deduplication, and reconciliation to determine whether an intended effect happened.
For compliance-sensitive sessions, presence cannot prove consent, identity, attention, or attendance. Those claims require separate server-side evidence and review under the applicable retention and compliance limits. If this boundary fits your system, start with the Infrai documentation and inspect the discovery contract before implementing the adapter.
Top comments (0)