Penyegerakan berbilang peranti (telefon mudah alih) - React Native
P粉151466081
2023-09-05 11:58:38
<p>Saya cuba mencipta Pertunjukan Cahaya yang akan dilancarkan pada semua peranti mudah alih pengguna pada masa yang sama (boleh mempunyai sehingga 2000-3000 pengguna). Semua pengguna akan menggunakan Internet (Wi-Fi atau data mudah alih). Di FE kami, kami menggunakan Apollo untuk langganan dan ia berfungsi seperti azimat. </p>
<p>Tetapi masalahnya ialah, pengguna A boleh mendapatkan acara langganan lebih cepat daripada pengguna B. Ini bermakna pengguna A akan mula bermain permainan lebih awal daripada pengguna B, yang merupakan masalah kerana kami mempunyai seni bina lighshow dan pengguna tidak boleh mula lebih awal atau lewat. Sebagai pengguna, anda akan melihat perbezaan serta-merta, dan ia tidak kelihatan baik. </p>
<p>Apa yang saya lihat ialah perbezaan kependaman boleh sehingga 300ms. Masa antara android (Xiaomi 9) dan ios (iPhone11) kebanyakannya sekitar 180ms+-. Jika kita membandingkan dua peranti iOS iPhone 11 dan iPhone 13, perbezaannya adalah sekitar 50-100 milisaat. Adakah terdapat cara untuk menghapuskan perbezaan ini, atau sekurang-kurangnya mengurangkannya kepada 40-60 ms untuk semua peranti? </p>
<p>Bermula dalam BE, kami menghantar masa pelayan (utc+0) dan pertunjukan cahaya akan bermula dengan cap waktu => Dalam FE, saya menambah 10 saat untuk memberi masa kepada semua peranti untuk menyelesaikan ciri, jadi permulaan ialah kelewatan-> "cap masa + 10 saat".</p>
<p>Dalam FE, saya menggunakan pustaka "react-native-ntp-client" untuk mendapatkan masa yang sama pada semua jenis peranti (ios/android, kerana saya mendapati masanya berbeza sedikit untuk setiap peranti). Saya kemudian mengira perbezaan antara "mula" dan "ntpTime" dan menyediakannya sebagai tamat masa kepada fungsi setTimeout saya, yang akan mencetuskan permulaan pertunjukan cahaya. </p>
<p>Di bawah saya telah memberikan contoh cara saya menggunakan skrin di mana paparan cahaya berada. </p>
<pre class="brush:php;toolbar:false;">import dayjs daripada 'dayjs';
import ntpClient daripada 'react-native-ntp-client';
eksport const LightshowScreen: React.FC<
LightshowScreenProps<'Lightshow'>
> = ({laluan}) =>
const {data, loading} = useSubscription(JOIN_LIGHTSHOW_SUBSCRIPTION, {
pembolehubah: {lightshowId: route.params.lightshow.id},
});
useEffect(() => {
const getServerTime = async (lightshowStartAt: number) =>
// Kelewatan mula 10s untuk menyediakan masa yang cukup untuk menyelesaikan fungsi kami - lightshowStartAt ialah cap masa dari pelayan kami
const lightshowStart = dayjs.unix(lightshowStartAt).add(10, 's');
ntpClient.getNetworkTime('time.cloudflare.com', 123, (ralat, tarikh) => {
jika (ralat) {
console.error('Tidak dapat menyambung', ralat);
kembali;
}
console.log('Tarikh klien NTP - ', tarikh // Isn Jul 08 2013 21:31:31 GMT+0200 (Paris, Madrid (heure d’été))
biarkan ntpTime = dayjs(tarikh);
// Perbezaan dalam ms
const diff = lightshowStart.diff(ntpTime);
// Selepas tamat masa ini semua peranti harus mula dimainkan pada masa yang sama
setTimeout(() => {
lightshowStartHandler();
}, perbezaan);
});
};
if (data && data?.joinLightshow.started) {
const lightshowData = data.lightshow;
getServerTime(lightshowData.startedAt);
}
}, [data]);
useEffect(() => {
if (data && data?.joinLightshow?.selesai) {
lightshowFinishHandler();
}
}, [data]);
kembali (
<Lihat gaya={style.container}>
....
</Lihat>
);
};</pre>
<p>Terima kasih atas semua komen dan pemikiran anda;)</p>
Apa yang anda mahu lakukan adalah sangat sukar. Menyegerakkan peranti sedemikian adalah sukar. Melakukan ini hampir mustahil apabila anda tidak memiliki dan mengawal perkakasan. Terus terang, saya tidak fikir anda akan mendapat apa yang anda mahukan.
Cap masa tidak akan berfungsi. Untuk satu, peranti ini tidak semua mempunyai masa yang sama. Mereka semua akan terkeluar sedikit. Idea anda seterusnya ialah menghantar masa kepada mereka daripada sumber pusat seperti pelayan anda. Masalahnya ialah menghantar data ke setiap peranti akan mengambil masa yang berbeza dan rawak. Anda boleh cuba meneka kependaman dengan mengira masa perjalanan pergi balik untuk sedozen paket, tetapi itu masih tekaan dan mungkin tidak tepat untuk paket seterusnya. NTP membantu memastikan masa peranti hampir pada masa yang sama, tetapi tidak setepat yang anda mahukan.
Walaupun ia mencapai ketepatan yang anda inginkan - Android bukan sistem pengendalian masa nyata. Tidak begitu dengan iPhone. Walaupun anda menetapkan penggera anda pada pukul 12:00:00, ia tidak akan menyala tepat pada pukul 12:00:00.000. Beberapa ketika selepas itu, ia akan menyala apabila sistem pengendalian mempunyai masa melahu, teras melahu dan menganggap aplikasi anda sebagai aplikasi berjadual yang paling penting. Ini mungkin mengambil masa ratusan milisaat. Terdapat sistem pengendalian yang boleh memberi anda janji yang anda inginkan. Dikenali sebagai sistem pengendalian masa nyata, ia sering digunakan dalam peranti terbenam yang tidak boleh gagal, seperti peralatan perubatan dan pengawal untuk mesin mahal. Mereka adalah pendekatan yang sama sekali berbeza untuk menulis sistem pengendalian daripada yang digunakan oleh peranti pengguna.
Saya sangat mengesyorkan anda memikirkan semula keperluan anda dan menjadi lebih realistik tentangnya. Terdapat teknologi yang membolehkan anda mendapatkan apa yang anda inginkan, tetapi bukan pada perkakasan rawak pada sistem pengendalian pengguna melalui Internet.
Selain itu, jika anda mahu melakukan ini - Saya benar-benar tidak mengesyorkan menggunakan React Native, ia menjalankan penterjemah dalam bahasa yang dikumpul sampah dan mempunyai pemasaan yang sangat rawak. Anda perlu sekurang-kurangnya menulis pelancar anda dalam C, kerana ini adalah pendekatan yang paling boleh diramal.
Tetapi sebenarnya, sila pertimbangkan semula keperluan anda. Mengapakah ia perlu bermula dalam masa 50 milisaat? Apabila anda melakukan sesuatu melalui internet, adakah ia benar-benar penting jika orang tidak segerak untuk seketika?