Gesaan dan konteks
Satu konsol pentadbir membolehkan pengguna membuka beberapa tab. Selepas pengguna log keluar, menukar tema, atau mengemas kini pemberitahuan dalam satu tab, tab lain harus menumpu (converge) dengan cepat. Muat semula, tab yang tidur, mesej pendua, dan pelayar tanpa BroadcastChannel tidak boleh merosakkan keadaan akhir. Reka bentuk protokol, pemulihan, sandaran, dan metrik pengesahan.
Ini adalah soalan penyelarasan pelayar untuk peranan frontend, web-platform, dan reka bentuk sistem frontend. Bilangan tab, kelewatan penyegerakan, dan jenis peristiwa adalah andaian temu duga, bukan jaminan pelayar. Tumpukan pada sempadan same-origin dan pemetakan storan (storage-partition) BroadcastChannel, akibat daripada mesej yang tidak tahan lama (non-persistent), pilihan antara peristiwa berbanding keadaan, dan bila untuk menggabungkannya dengan localStorage, IndexedDB, SharedWorker, atau Web Locks.
Perkara yang diuji oleh penemu duga
Pertama, bolehkah anda menyatakan sempadan API? BroadcastChannel menghantar mesej antara tetingkap, tab, bingkai (frames), dan worker yang berkongsi origin yang sama dan pemetakan storan yang boleh berkomunikasi. Ia bukan pengangkutan rentas-origin, baris gilir tahan lama (durable queue), atau perkhidmatan ketekalan teragih.
Kedua, bolehkah anda mereka bentuk protokol idempoten? Mesej boleh berulang, penghantar tidak menerima siarannya sendiri, dan halaman penerima mungkin ditutup atau tidur. Mesej yang hanya mengatakan "tema telah berubah" tanpa versi dan laluan bacaan semula menyebabkan keadaan menjadi lapuk secara kekal.
Ketiga, bolehkah anda memisahkan pemberitahuan daripada sumber kebenaran (source of truth)? Log keluar boleh menyiarkan pembatalan, perubahan tema boleh disimpan secara kekal dan kemudian diumumkan, dan kemas kini pemberitahuan harus membuatkan penerima membaca semula cache yang berwibawa dan bukannya menganggap senarai penuh dalam mesej sebagai kebenaran.
Akhir sekali, bolehkah anda mengendalikan kitaran hayat dan sandaran: menutup saluran, menjauhkan token daripada mesej, mengesan keupayaan, menggunakan peristiwa storan atau bacaan semula pelayan, dan mengukur bahawa penyegerakan tidak mewujudkan gelung atau kebocoran memori?
Soalan untuk dijelaskan terlebih dahulu
- Adakah muatan itu peristiwa sekali sahaja, keadaan semasa, atau sejarah yang boleh dimainkan semula? Itu menentukan sama ada versi yang berterusan diperlukan.
- Adakah skopnya satu origin, iframe di bawah tapak peringkat teratas yang sama, atau subdomain berbeza? Pemetakan storan boleh menghalang komunikasi walaupun origin kelihatan berkaitan.
- Bolehkah satu mesej hilang? Log keluar, pembatalan kebenaran, dan konflik suntingan memerlukan jaminan pemulihan yang berbeza.
- Di manakah sumber kebenaran: pelayan, IndexedDB, localStorage, cache dalam memori, atau Service Worker?
- Adakah satu tab mesti menjadi satu-satunya penulis untuk muat semula, migrasi, atau kerja kelompok? BroadcastChannel tidak menyediakan kunci (lock).
- Apakah matriks pelayar, termasuk mod peribadi, pembekuan latar belakang, dan bilangan tab yang dijangkakan?
- Mungkinkah mesej mengandungi data profil, kebenaran, atau token? Jika ya, gantikannya dengan isyarat pembatalan yang tidak sensitif.
Jawapan 30 saat
"Saya akan menggunakan BroadcastChannel sebagai bas pemberitahuan kependaman rendah, bukan sebagai sumber keadaan yang tahan lama. Setiap mesej membawa versi protokol, jenis peristiwa, jujukan monotonik atau versi keadaan, dan ID surih. Penerima mengesahkan bentuk, menggunakan peristiwa secara idempoten, dan membaca semula localStorage, IndexedDB, atau pelayan apabila jurang versi muncul. Log keluar menghantar pembatalan, tema menulis keutamaan berterusan, dan perubahan pemberitahuan mencetuskan bacaan semula. Jika API tidak tersedia, gunakan peristiwa storan atau pengundian (polling); jika satu penulis diperlukan, gunakan Web Locks atau penyelarasan pelayan. Tutup setiap saluran semasa perobohan (teardown) dan ukur kependaman, pemulihan mesej yang hilang, dan pengendalian pendua."
Jawapan langkah demi langkah
Langkah 1: Tentukan mesej dan keadaan berwibawa
Tetapkan sumber kebenaran bagi setiap ciri. Tema dan bahasa ialah keutamaan yang boleh berada dalam tetapan berterusan. Pemberitahuan dan kebenaran harus dibaca semula daripada pelayan atau cache setempat. Log keluar ialah isyarat pembatalan sesi; jangan sekali-kali meletakkan token akses dalam mesej. Siarkan hanya type, version, entityKey, updatedAt, atau traceId yang tidak sensitif.
MDN menerangkan bahawa BroadcastChannel menyokong komunikasi dua hala antara konteks pelayaran same-origin dan worker, manakala aplikasi mentakrifkan protokol mesej; platform ini tidak menyediakan perundingan. Pemversian, pengendalian peristiwa yang tidak diketahui, dan pengesahan medan adalah tanggungjawab aplikasi.
Langkah 2: Mengendalikan pendua, susunan, dan kehilangan
Kekalkan versi terakhir yang diproses untuk setiap domain keadaan. Abaikan mesej yang versinya lebih lama atau sama; versi yang lebih baharu secara berterusan boleh mencetuskan satu bacaan semula; lompatan menandakan jurang dan memulakan penyegerakan syot kilat (snapshot sync). Jika perniagaan mendedahkan peristiwa tanpa versi, gunakan ID penyahduplikasian dan set diproses yang terhad, sambil mengakui bahawa ini tidak dapat membuktikan bahawa peristiwa perantara tidak hilang.
Jangan anggap penghantaran terjamin. Penghantar tidak menerima mesejnya sendiri, dan tab yang baru dibuka atau tidur boleh terlepasnya. Semasa permulaan, muatkan keadaan berterusan atau syot kilat pelayan sebelum melanggan; siaran itu hanya mengurangkan kependaman kesegaran data.
Langkah 3: Pilih ketahanan dan penyelarasan bersama
localStorage sesuai untuk keutamaan kecil dan boleh mencetuskan peristiwa storan; ia bukan pangkalan data thông lượng tinggi (high-throughput) atau tempat untuk token. IndexedDB sesuai untuk cache setempat yang lebih besar dan syot kilat berversi. Service Worker boleh mengambil bahagian dalam penyegerakan latar belakang, tetapi ia harus menulis hasil kepada storan yang boleh dipulihkan.
BroadcastChannel menyelesaikan pemberitahuan kepada pelbagai konteks, bukan penyelarasan penulis tunggal (single-writer coordination). Jika satu tab sahaja boleh memuat semula cache, menjalankan migrasi, atau menyerahkan kelompok, gunakan Web Locks. Tanpa kunci, sertakan syarat versi dan biarkan pelayan membuat timbang tara. SharedWorker sesuai untuk sambungan dikongsi atau keadaan berpusat, tetapi menambah kerumitan kitaran hayat dan keserasian.
Langkah 4: Bina penerimaan selamat dan sandaran
Terima jenis peristiwa yang disenarai putih sahaja, hadkan saiz mesej, dan tolak versi yang tidak diketahui atau skema yang tidak sah. Jangan sekali-kali meletakkan token akses, profil penuh, atau HTML yang boleh dilaksanakan dalam mesej. Semasa log keluar, kosongkan cache setempat yang sensitif dan navigasi ke daftar masuk; pada peristiwa tema, kemas kini UI tetapi percayai tetapan yang disimpan secara berterusan.
Jika pengesanan keupayaan gagal, gunakan peristiwa storan untuk keadaan kecil. Jika itu tidak tersedia atau dipetakkan, baca semula pada pemfokusan (focus), lakukan pengundian seketika, atau gunakan tolakan pelayan (server push). Sandaran mestilah selamat untuk diulang; ketiadaan siaran tidak boleh menjadi capahan kekal.
Langkah 5: Urus sumber dan sahkan tingkah laku
Alih keluar pendengar dan panggil close() apabila komponen atau halaman dimusnahkan. Jangan buat saluran baharu pada setiap pemaparan (render). Gunakan ruang nama (namespace) supaya aplikasi yang tidak berkaitan tidak melanggan nama yang sama. Sertakan label sumber dan ID surih supaya penerima tidak menyiarkan semula mesej yang sama dalam gelung.
Uji kelewatan hujung ke hujung berbilang tab, pendua dan penyusunan semula, penyambungan semula selepas tidur, syot kilat awal selepas muat semula, sandaran storan, pengasingan pemetakan storan, penutupan saluran, mesej bersaiz besar, gelung, dan pertukaran pengguna. Jejaki kejayaan pengendali, jurang versi, bacaan semula, pendua yang dibuang, masa pemulihan, dan saluran yang dibiarkan terbuka.
Contoh jawapan berkualiti tinggi
"Saya akan mentakrifkan BroadcastChannel sebagai bas pemberitahuan, bukan baris gilir. Log keluar hanya membawa jenis pembatalan sesi dan versi. Kemas kini tema menulis localStorage dan menyiarkan versi keutamaan baharu. Kemas kini pemberitahuan menyiarkan kunci entiti dan versi, jadi setiap penerima membaca semula daripada pelayan atau IndexedDB. Mesej tidak mengandungi sebarang token atau data pengguna yang lengkap.
Setiap mesej mempunyai versi protokol, versi keadaan monotonik, dan ID surih. Penerima menolak bentuk yang tidak diketahui, membuang versi yang telah diproses atau lebih lama, dan mengambil syot kilat apabila mereka melihat jurang. Permulaan memuatkan syot kilat sebelum melanggan kerana tab baharu atau tab yang tidur boleh terlepas siaran, dan penghantar tidak menerima mesejnya sendiri.
Jika penyegaran semula cache memerlukan seorang penulis, saya akan menambah Web Locks; BroadcastChannel sahaja tidak boleh menghalang dua tab daripada menulis secara serentak. Pelayar yang tidak disokong menggunakan peristiwa storan untuk keutamaan kecil dan bacaan semula masa fokus atau pengundian pendek untuk data lain. Perobohan mengalih keluar pendengar dan menutup saluran. Metrik merangkumi kelewatan, jurang, pendua, masa pemulihan, dan sumber yang bocor. Ini memisahkan pemberitahuan kependaman rendah, keadaan yang boleh dipulihkan, dan keserasian pelayar."
Mod kegagalan biasa
- Menganggap siaran sebagai baris gilir yang tahan lama → tab baharu atau tab yang tidur terlepas peristiwa → muatkan syot kilat terlebih dahulu dan gunakan mesej sebagai petunjuk.
- Meletakkan token atau keadaan penuh dalam mesej → memperluas pendedahan data sensitif dan konflik versi → hantar hanya peristiwa, kunci, dan versi yang tidak sensitif.
- Tiada versi atau ID penyahduplikasian → pendua dan penyusunan semula mengundurkan UI ke belakang → gunakan versi monotonik, pengendalian idempoten, dan bacaan semula jurang.
- Menganggap same-origin bermaksud keterhubungan terjamin → pemetakan storan boleh mengasingkan konteks → uji sempadan sebenar dan sediakan sandaran.
- Menggunakan BroadcastChannel sebagai kunci → dua tab masih boleh menulis secara serentak → gunakan Web Locks atau penulisan pelayan bersyarat.
- Mencipta saluran pada setiap render → pendengar dan sumber bocor → kekalkan tika (instance) yang stabil, alih keluar pendengar, dan tutupnya.
- Menyiarkan semula setiap mesej yang diterima → mewujudkan gelung → bawa ID sumber/surih dan hantar hanya pada perubahan keadaan.
- Menganggap peristiwa storan sebagai pengganti lengkap → ia hanya meliputi beberapa penulisan dan bukan tetingkap yang sama → dokumenkan perbezaan dan tambah bacaan semula.
Soalan susulan
Susulan 1: Dua tab menyunting borang yang sama. Bagaimanakah anda mengelakkan penulisan ganti (overwriting)?
Siarkan bahawa versi sumber telah berubah; jangan tulis ganti draf setempat. Serahkan versi asas, biarkan pelayan menolak penulisan bersyarat yang lapuk, dan tunjukkan konflik untuk penggabungan pengguna. Keutamaan setempat boleh menggunakan Web Locks untuk penulisan bersiri.
Susulan 2: Tab bangun selepas tidur selama 20 minit. Bagaimanakah ia mengejar perubahan terkini?
Baca semula syot kilat pelayan atau IndexedDB semasa disambung semula, bandingkan versi keadaan, dan kemudian proses sebarang isyarat berperingkat. Jangan bergantung pada siaran terakhir. Jika syot kilat tidak tersedia, tandakan keadaan sebagai lapuk dan perlukan pengesahan semula atau tunjukkan keadaan tamat tempoh yang jelas.
Susulan 3: Halaman pada subdomain berbeza perlu berkomunikasi. Adakah BroadcastChannel menyelesaikannya?
Jangan anggap ia boleh. BroadcastChannel dikekang oleh origin dan pemetakan storan. Komunikasi rentas-origin memerlukan hubungan tetingkap postMessage yang jelas atau penyelarasan pelayan, dengan semakan origin, skema, dan kebenaran; jangan melemahkan sempadan keselamatan semata-mata untuk berkongsi saluran.
Susulan 4: Hanya satu tab harus mengekalkan WebSocket. Bagaimanakah anda mereka bentuknya?
BroadcastChannel boleh berkongsi keadaan sambungan dan data tetapi tidak boleh memilih ketua. Utamakan Web Locks untuk pemegang, dengan tab lain melanggan siarannya; pilih semula selepas pemegang ditutup atau kehilangan kunci. Jika tidak tersedia, gunakan pajakan (lease) pelayan atau benarkan berbilang sambungan dengan penyahduplikasian pihak pelayan dan pertukaran kos (cost trade-off) yang jelas.