Sign inGet Started

Kotlin SDK

com.messagebird:bird-realtime è il client Kotlin ufficiale per Bird Realtime: mantiene un WebSocket verso l'edge Bird, sottoscrive i canali e consegna gli eventi man mano che vengono pubblicati. È scritto a mano anziché generato, perché Realtime è un data plane WebSocket e non una superficie REST, e parla lo stesso dialetto wire dei client browser e Swift.

È una libreria JVM pura, quindi lo stesso artefatto serve sia un'app Android sia un server. I callback atterrano sul main looper di Android quando è presente, altrimenti vengono eseguiti inline, perciò non serve una build separata per ciascun caso.

Questo client è il lato di ricezione. Pubblicare eventi, autorizzare canali e terminare connessioni sono operazioni lato server sulla Bird API; vedi pubblicare eventi.

Installazione

Esempio di codice
dependencies {
    implementation("com.messagebird:bird-realtime:0.1.0")
}

Su Android, aggiungi il permesso internet al manifest. Una libreria non ne contribuisce più uno:

Esempio di codice
<uses-permission android:name="android.permission.INTERNET" />

Costruire un client

Esempio di codice
import com.messagebird.realtime.BirdRealtime
import com.messagebird.realtime.BirdRealtimeOptions

val bird = BirdRealtime(
    BirdRealtimeOptions(
        appKey = "your-app-key",
        region = "us1",
    )
)

Solo appKey è obbligatorio, più region (us1 o eu1, che risolve l'host edge) oppure un wsHost esplicito. La app key è pubblica e viene distribuita nel codice client: identifica l'app, non autorizza nulla.

Il socket si apre quando il client viene costruito, quindi non serve chiamare prima connect(). connect() e disconnect() servono per il ciclo di vita dell'app: chiudi il socket quando la tua activity scompare e riaprilo quando torna, e i canali a cui ti eri sottoscritto vengono ri-sottoscritti automaticamente.

disconnect() lascia il client riutilizzabile, perciò mantiene intenzionalmente il worker thread su cui il client confina il proprio stato. Quando hai finito definitivamente con un client, esegui close(), altrimenti quel thread e il socket vivono per tutta la durata del processo. La classe è AutoCloseable, quindi un blocco use { } lo fa per te. Il client Swift non ha bisogno di un equivalente: rilascia entrambi quando l'ultimo riferimento viene rimosso.

Sottoscrivere un canale

Esempio di codice
val orders = bird.subscribe("orders")
orders.bind("order-updated") { data ->
    println("order changed: $data")
}

I payload arrivano come kotlinx.serialization.json.JsonElement, quindi leggili con la API di serializzazione anziché fare il casting.

Un canale il cui nome non ha il prefisso private- o presence- è pubblico: qualsiasi client con la app key può sottoscriverlo, quindi considera i suoi contenuti leggibili da chiunque possa aprire la tua app.

Canali private e presence

I canali private e presence sono autorizzati dal tuo backend, che detiene il secret dell'app. Punta il client al tuo endpoint: esegue un POST di {"connection_id", "channel_name"} e si aspetta {"auth", "member_data"?} in risposta.

Esempio di codice
val bird = BirdRealtime(
    BirdRealtimeOptions(
        appKey = "your-app-key",
        region = "us1",
        authEndpoint = "https://your-backend.example.com/bird/auth",
        authHeaders = mapOf("authorization" to "Bearer <session token>"),
    )
)

val room = bird.subscribe("presence-room-42")
if (room is PresenceChannel) {
    room.bind(BirdProtocol.Event.SUBSCRIPTION_SUCCEEDED) {
        println("me: ${room.myId}, members: ${room.members.keys}")
    }
    room.bind(BirdProtocol.Event.MEMBER_ADDED) { member -> println("joined: $member") }
}

Passa un authorizer per firmare tramite il tuo stack di rete.

Un rifiuto dal server (firma non valida, app oltre la capacità) arriva sulla connessione anziché sul canale, perché il wire non porta l'attribuzione al canale. Osserva questi eventi con onError. Un errore all'interno del tuo authorizer emette invece bird:subscription_error sul canale.

Eseguire il sign-in di un membro

signin() comunica all'edge a quale membro appartiene questa connessione. Quell'identità è ciò che consente alla API di indirizzare un membro o terminare le sue connessioni, ed è ciò che soddisfa un'app configurata per richiedere connessioni autorizzate.

Esempio di codice
val bird = BirdRealtime(
    BirdRealtimeOptions(
        appKey = "your-app-key",
        region = "us1",
        memberAuthEndpoint = "https://your-backend.example.com/bird/auth/member",
    )
)

val me = bird.signin() // suspending
println("signed in as ${me.memberId}")

bird.member.bind("order.shipped") { data ->
    println("addressed to me: $data")
}

Chiama signin() una sola volta. L'identità resta sulla connessione, quindi il client esegue di nuovo il sign-in automaticamente dopo una riconnessione. Un sign-in automatico fallito non ha una chiamata attiva da cui lanciare un'eccezione, perciò compare su onSigninError. Questo evita che un endpoint membro in errore interferisca con le sottoscrizioni ai canali.

Ciclo di vita della connessione

Esempio di codice
bird.onConnectionStateChange { previous, current ->
    println("connection: $previous -> $current")
}
bird.onError { error ->
    if (error.code == 4009) println("session ended elsewhere")
}

La riconnessione è automatica, con backoff esponenziale full-jitter da 1 s fino a un tetto di 30 s. I codici di chiusura nell'intervallo 4000–4099 sono rifiuti e terminali: il client si ferma e segnala il codice, perché un rifiuto è una decisione, non un errore transitorio. I codici nell'intervallo 4200–4299 si riconnettono immediatamente; tutto il resto applica il backoff. I canali si ri-sottoscrivono con autorizzazione aggiornata a ogni riconnessione. Vedi ciclo di vita della connessione.

Il trasporto è TLS per ogni host non-loopback. allowInsecure consente ws:// solo per localhost, 127.0.0.1 e [::1], così una configurazione copiata da un target di sviluppo non può declassare silenziosamente il traffico di produzione.

Eventi client

Con l'impostazione client-events dell'app abilitata, un client sottoscritto a un canale private o presence può pubblicare direttamente ai suoi peer:

Esempio di codice
room.trigger("client-typing", buildJsonObject { put("on", true) })

Vedi eventi client.

Sorgente

github.com/messagebird/bird-sdk-kotlin, licenza MIT. Segnala i problemi lì.

Continua con la documentazione, le guide e gli esempi per questo argomento.