Siklus hidup koneksi dan rekoneksi
Koneksi Realtime adalah satu WebSocket. Perubahan jaringan, perangkat yang tertidur, dan restart infrastruktur dapat menutupnya. Klien melakukan rekoneksi secara otomatis, sementara aplikasi Anda dapat menampilkan state koneksi saat ini.
Enam state
bird.connection.state di klien browser, dan bird.connectionState di Swift dan Kotlin, selalu salah satu dari berikut (Kotlin menulisnya sebagai konstanta ConnectionState, jadi unavailable terbaca ConnectionState.UNAVAILABLE):
| State | Artinya |
|---|---|
| initialized | Klien sudah ada tetapi belum membuka socket. |
| connecting | Socket sedang dibuka, atau sudah terbuka dan menunggu handshake. |
| connected | Handshake berhasil. Koneksi memiliki ID dan dapat subscribe. |
| unavailable | Koneksi terputus dan rekoneksi dijadwalkan. |
| disconnected | Anda memanggil disconnect(). Tidak ada yang dijadwalkan. |
| failed | Server menolak koneksi ini. Klien tidak mencoba ulang. |
Bind state_change untuk melihat setiap transisi, atau bind satu nama state jika hanya satu yang penting:
import { BirdRealtime } from "@messagebird/realtime";
const bird = new BirdRealtime({ appKey: "your-app-key", region: "us1" });
bird.connection.bind("state_change", ({ previous, current }) => {
console.log(previous, "->", current);
});
bird.connection.bind("unavailable", () => showReconnectingBanner());
bird.connection.bind("connected", () => hideReconnectingBanner());import BirdRealtime
let bird = BirdRealtime(options: .init(appKey: "your-app-key", region: "us1"))
bird.onConnectionStateChange { previous, current in
print(previous, "->", current)
if current == .unavailable { showReconnectingBanner() }
if current == .connected { hideReconnectingBanner() }
}import com.bird.realtime.BirdRealtime
import com.bird.realtime.BirdRealtimeOptions
import com.bird.realtime.ConnectionState
val bird = BirdRealtime(BirdRealtimeOptions(appKey = "your-app-key", region = "us1"))
bird.onConnectionStateChange { previous, current ->
println("$previous -> $current")
if (current == ConnectionState.UNAVAILABLE) showReconnectingBanner()
if (current == ConnectionState.CONNECTED) hideReconnectingBanner()
}Swift dan Kotlin menggunakan satu observer untuk setiap transisi, jadi lakukan branch pada current. Handler berjalan di main queue pada Swift dan di Android main looper pada Kotlin jika tersedia. Berikan deliveryQueue atau Executor untuk menggunakan konteks eksekusi lain.
Socket yang terbuka tetap dalam connecting sampai handshake dari server tiba. Handshake menetapkan bird.connection.connectionId sebelum state menjadi connected, sehingga otorisasi dapat menandatangani ID tersebut. Jika handshake tidak menyertakan ID, klien melaporkan error dan menutup socket.
Rekoneksi otomatis
Setelah terputus secara tidak terduga, klien menunggu sebelum membuka socket baru. Jeda menggunakan exponential backoff dengan full-jitter, basis satu detik, dan batas maksimum 30 detik. Setiap handshake yang berhasil mereset backoff.
Close code menentukan mana dari tiga hal berikut yang terjadi:
| Close code | Perilaku |
|---|---|
| 4000 sampai 4099 | Ditolak. Tidak ada retry, state menjadi failed. |
| 4200 sampai 4299 | Retry segera. |
| Lainnya | State menjadi unavailable, lalu retry dengan backoff. |
Kegagalan jaringan menggunakan jalur backoff. Tangani kode penolakan di UI Anda karena kegagalan terminal ini tidak melakukan rekoneksi secara otomatis.
Pemeriksaan koneksi basi
Socket bisa tampak terbuka setelah jalur jaringannya gagal. Klien mengirim ping setelah activity timeout, yang default-nya 120 detik kecuali handshake memberikan nilai lain. Jika tidak ada pong yang tiba dalam pong timeout default 30 detik, klien menutup socket dengan kode retry-immediately.
Apa yang terjadi pada channel Anda
Subscription terikat pada koneksi, jadi pemutusan menghapusnya. Klien mempertahankan setiap objek channel, melakukan subscribe ulang setelah state connected berikutnya, dan menjaga handler yang ada.
Klien memanggil authEndpoint Anda kembali untuk setiap private channel dan presence channel menggunakan connection ID baru. Klien tidak dapat menggunakan ulang signature lama karena signature tersebut menyertakan connection ID sebelumnya. Setelah satu panggilan signin(), klien juga melakukan sign in pada setiap koneksi baru dan melaporkan kegagalan berikutnya melalui signin_error.
bird.connection.bind("signin_error", ({ message }) => {
console.warn("connection has no identity:", message);
});bird.onSigninError { error in
print("connection has no identity:", error.message)
}bird.onSigninError { error ->
println("connection has no identity: ${error.message}")
}Saat channel sedang melakukan rekoneksi, channel.trigger mengembalikan false tanpa mengirim client event. Periksa channel.subscribed, atau kirim setelah bird:subscription_succeeded, yang dijalankan setelah setiap re-subscription yang berhasil.
const room = bird.subscribe("presence-room-1");
room.bind("bird:subscription_succeeded", ({ members }) => {
renderMembers(members);
});guard let room = bird.subscribe("presence-room-1") as? PresenceChannel else { return }
room.bind(BirdProtocol.Event.subscriptionSucceeded) { _ in
renderMembers(room.members)
}val room = bird.subscribe("presence-room-1")
if (room is PresenceChannel) {
room.bind(BirdProtocol.Event.SUBSCRIPTION_SUCCEEDED) {
renderMembers(room.members)
}
}Realtime tidak memutar ulang event yang diterbitkan saat klien terputus. Jika sebuah view harus pulih setelah jeda, ambil state terkininya pada bird:subscription_succeeded dan terapkan event berikutnya dari sana.
Memutus koneksi secara sengaja
bird.disconnect() menutup socket tanpa menjadwalkan rekoneksi. Gunakan saat klien yang sudah sign out atau tidak aktif tidak lagi membutuhkan data real-time. Klien mempertahankan channel, sehingga bird.connect() di kemudian waktu membuka kembali socket dan melakukan subscribe ulang.
bird.disconnect(); // state: disconnected, no reconnect
bird.connect(); // reopens and re-subscribesbird.disconnect() // state: disconnected, no reconnect
bird.connect() // reopens and re-subscribesbird.disconnect() // state: DISCONNECTED, no reconnect
bird.connect() // reopens and re-subscribesDi perangkat mobile, putuskan koneksi saat view atau activity yang relevan berhenti dan sambungkan kembali saat dilanjutkan. Objek channel dan binding tetap tersedia.
Error pada koneksi versus error pada channel
Error server yang terkait satu channel tiba di channel tersebut. Subscription yang ditolak adalah kasus paling umum, dan authorizer yang mengembalikan 403 muncul di sini:
room.bind("bird:subscription_error", (err) => {
console.warn("could not join:", err);
});room.bind(BirdProtocol.Event.subscriptionError) { error in
print("could not join:", error ?? "")
}room.bind(BirdProtocol.Event.SUBSCRIPTION_ERROR) { error ->
println("could not join: $error")
}Semua yang tidak diatribusikan oleh wire ke channel tertentu tiba di koneksi:
bird.connection.bind("error", ({ code, message }) => {
console.warn(code, message);
});bird.onError { error in
print(error.code ?? 0, error.message)
}bird.onError { error ->
println("${error.code} ${error.message}")
}Menangani close code 4009
Kode 4009 berada di band no-retry, sehingga koneksi memasuki failed. Periksa reason untuk membedakan situasi berikut:
- Member yang diterminasi. Backend Anda memanggil disconnect API untuk member ini, sehingga setiap koneksi yang mereka miliki ditutup. Lihat Menterminasi koneksi member.
- Koneksi yang tidak pernah diotorisasi. Aplikasi mewajibkan koneksi yang diotorisasi dan koneksi ini tidak melakukan otorisasi tepat waktu. Lihat Mewajibkan koneksi yang diotorisasi.
Klien tidak melakukan rekoneksi secara otomatis, jadi aplikasi Anda yang menentukan apa yang terjadi selanjutnya:
bird.connection.bind("error", ({ code }) => {
if (code === 4009) showSignedOutScreen();
});bird.onError { error in
if error.code == 4009 { showSignedOutScreen() }
}bird.onError { error ->
if (error.code == 4009) showSignedOutScreen()
}State signed-out sesuai ketika autentikasi telah berakhir. Memanggil bird.connect() memulai koneksi baru dan mengulangi otorisasi, jadi lakukan rekoneksi hanya setelah state otorisasi pemanggil berubah.
Langkah selanjutnya
- Mengotorisasi channel adalah kontrak yang diimplementasikan backend Anda, dan permintaan yang diulang klien pada setiap rekoneksi.
- Mewajibkan koneksi yang diotorisasi mengubah koneksi yang tidak diotorisasi menjadi koneksi yang ditutup.
- Menterminasi koneksi member adalah cara koneksi ditutup dengan 4009 secara sengaja.
- Gambaran umum Realtime mencakup channel, member, dan koneksi sebagai sebuah model.
Sumber daya terkait
Lanjutkan dengan dokumentasi, panduan, dan contoh untuk topik ini. Sumber daya tersedia dalam bahasa Inggris.
Jelajahi kemampuannyaRealtimeIkuti jalur pembelajaranBuild your first integrationPanduan implementasiSend your first realtime event
Coba praktiknya dan dapatkan ringkasan implementasi