Kotlin SDK
com.messagebird:bird-realtime is de officiële Kotlin-client voor Bird Realtime: hij houdt een WebSocket open naar de Bird-edge, abonneert zich op kanalen en levert events af zodra ze gepubliceerd worden. Hij is met de hand geschreven in plaats van gegenereerd, omdat Realtime een WebSocket-dataplane is en geen REST-oppervlak, en hij spreekt hetzelfde draadprotocol als de browser- en Swift-clients.
Het is een gewone JVM-library, dus hetzelfde artefact werkt voor een Android-app en een server. Callbacks komen op de Android main looper terecht als die bestaat, en draaien anders inline, dus je hebt geen aparte build nodig voor elk platform.
Deze client is de ontvangende kant. Events publiceren, kanalen autoriseren en verbindingen beëindigen zijn serveroperaties op de Bird API; zie events publiceren.
Installeren
dependencies {
implementation("com.messagebird:bird-realtime:0.1.0")
}Voeg op Android de internetpermissie toe aan je manifest. Een library draagt er zelf geen meer bij:
<uses-permission android:name="android.permission.INTERNET" />Een client aanmaken
import com.messagebird.realtime.BirdRealtime
import com.messagebird.realtime.BirdRealtimeOptions
val bird = BirdRealtime(
BirdRealtimeOptions(
appKey = "your-app-key",
region = "us1",
)
)Alleen appKey is vereist, plus ofwel region (us1 of eu1, die de edge-host bepaalt) of een expliciete wsHost. De app key is publiek en zit in de clientcode: hij identificeert de app, hij autoriseert niets.
De socket opent zodra de client wordt aangemaakt, dus je hoeft niet eerst connect() aan te roepen. connect() en disconnect() zijn bedoeld voor de app-levenscyclus: sluit de socket als je activity verdwijnt en heropen hem als die terugkomt, en de kanalen waarop je geabonneerd was worden automatisch opnieuw geabonneerd.
disconnect() laat de client herbruikbaar, dus hij houdt bewust de workerthread waarop de client zijn state beperkt. Als je definitief klaar bent met een client, close() hem, anders blijven die thread en de socket bestaan zolang het proces draait. De class is AutoCloseable, dus een use { }-blok doet dat voor je. De Swift-client heeft geen equivalent nodig: hij geeft beide vrij zodra de laatste referentie verdwijnt.
Abonneren op een kanaal
val orders = bird.subscribe("orders")
orders.bind("order-updated") { data ->
println("order changed: $data")
}Payloads komen binnen als kotlinx.serialization.json.JsonElement, dus lees ze met de serialisatie-API in plaats van te casten.
Een kanaal waarvan de naam geen private-- of presence--prefix heeft, is publiek: elke client met de app key kan zich abonneren, dus beschouw de inhoud als leesbaar voor iedereen die je app kan openen.
Private en presence channels
Private en presence channels worden geautoriseerd door je backend, die het app secret bevat. Wijs de client naar je endpoint: hij POST {"connection_id", "channel_name"} en verwacht {"auth", "member_data"?} terug.
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") }
}Geef in plaats daarvan een authorizer mee om via je eigen netwerkstack te ondertekenen.
Een afwijzing van de server (een ongeldige handtekening, een app die zijn capaciteit overschrijdt) komt binnen op de verbinding in plaats van op het kanaal, omdat het draadprotocol geen kanaalattributie bevat. Observeer die met onError. Een fout in je authorizer genereert wel bird:subscription_error op het kanaal.
Een lid aanmelden
signin() vertelt de edge bij welk lid deze verbinding hoort. Die identiteit is wat de API in staat stelt een lid te adresseren of diens verbindingen te beëindigen, en het is wat voldoet aan een app die geconfigureerd is om geautoriseerde verbindingen te vereisen.
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")
}Roep signin() één keer aan. De identiteit blijft op de verbinding staan, dus de client meldt zich na een herverbinding automatisch opnieuw aan. Een mislukte automatische aanmelding heeft geen actieve aanroep om vanuit te throwen, dus verschijnt op onSigninError. Dit voorkomt dat een falend member-endpoint kanaalabonnementen verstoort.
Verbindingslevenscyclus
bird.onConnectionStateChange { previous, current ->
println("connection: $previous -> $current")
}
bird.onError { error ->
if (error.code == 4009) println("session ended elsewhere")
}Herverbinding is automatisch, met full-jitter exponentiële backoff van 1 s tot een plafond van 30 s. Sluitcodes in 4000–4099 zijn weigeringen en definitief: de client stopt en rapporteert de code, omdat een weigering een beslissing is en geen tijdelijke fout. Codes in 4200–4299 verbinden direct opnieuw; al het andere valt terug op backoff. Kanalen worden bij elke herverbinding opnieuw geabonneerd met verse autorisatie. Zie verbindingslevenscyclus.
Transport is TLS voor elke niet-loopback-host. allowInsecure staat ws:// alleen toe voor localhost, 127.0.0.1 en [::1], dus een configuratie gekopieerd van een development-target kan productieverkeer niet stilletjes downgraden.
Client events
Als de client-events-instelling van de app is ingeschakeld, kan een client die geabonneerd is op een private of presence channel rechtstreeks naar zijn peers publiceren:
room.trigger("client-typing", buildJsonObject { put("on", true) })Zie client events.
Broncode
github.com/messagebird/bird-sdk-kotlin, MIT-licentie. Meld problemen daar.
Gerelateerde bronnen
Ga verder met de documentatie, handleidingen en voorbeelden voor dit onderwerp.