多裝置(手機)同步 - React Native
P粉151466081
P粉151466081 2023-09-05 11:58:38
0
1
703
<p>我正在嘗試建立 Lightshow,它將同時在所有用戶的行動裝置上啟動(最多可以有 2000-3000 個用戶)。所有用戶都將使用網路(Wi-Fi 或行動數據)。在我們的 FE,我們使用 Apollo 進行訂閱,這就像一個魅力。 </p> <p>但問題是,用戶 A 可以比用戶 B 更快地獲取訂閱事件。這意味著用戶 A 將比用戶 B 更早開始玩遊戲,這是一個問題,因為我們有 lighshow 架構,而用戶可以『不能早點或晚點開始。作為用戶,您會立即看到差異,而且看起來不太好。 </p> <p>我看到的是延遲差異可以達到300ms。 android (小米 9) 與 ios (iPhone11) 之間的時間大多約為 180ms -。如果我們比較兩台 iOS 裝置 iPhone 11 和 iPhone 13,差異約為 50-100 毫秒。對於所有設備,有沒有辦法消除這種差異,或至少將其降低到 40-60 毫秒? </p> <p>從BE 開始,我們發送伺服器時間(utc 0),燈光秀將以時間戳開始=> 在FE 中,我添加10 秒來為所有設備提供解決該功能的時間,因此啟動被延遲-> "時間戳10 秒」。</p> <p>在 FE 中,我使用庫“react-native-ntp-client”在所有類型的設備上獲得相同的時間(ios/android,因為我發現每個設備的時間略有不同)。然後我計算“start”和“ntpTime”之間的差異,並將其作為超時提供給我的 setTimeout 函數,這將觸發燈光秀的開始。 </p> <p>下面我提供了一個範例,說明我如何使用燈光秀所在的螢幕。 </p> <pre class="brush:php;toolbar:false;">import dayjs from 'dayjs'; import ntpClient from 'react-native-ntp-client'; export const LightshowScreen: React.FC< LightshowScreenProps<'Lightshow'> > = ({route}) => { const {data, loading} = useSubscription(JOIN_LIGHTSHOW_SUBSCRIPTION, { variables: {lightshowId: route.params.lightshow.id}, }); useEffect(() => { const getServerTime = async (lightshowStartAt: number) => { // Delay start 10s to provide enough time to finish our functions - lightshowStartAt is timestamp from our server const lightshowStart = dayjs.unix(lightshowStartAt).add(10, 's'); ntpClient.getNetworkTime('time.cloudflare.com', 123, (error, date) => { if (error) { console.error('Cant connect', error); return; } console.log('NTP client date - ', date); // Mon Jul 08 2013 21:31:31 GMT 0200 (Paris, Madrid (heure d’été)) let ntpTime = dayjs(date); // Diff in ms const diff = lightshowStart.diff(ntpTime); // After this timeout all devices should start play at the same time setTimeout(() => { lightshowStartHandler(); }, diff); }); }; if (data && data?.joinLightshow.started) { const lightshowData = data.lightshow; getServerTime(lightshowData.startedAt); } }, [data]); useEffect(() => { if (data && data?.joinLightshow?.finished) { lightshowFinishHandler(); } }, [data]); return ( <View style={style.container}> .... </View> ); };</pre> <p>感謝您的所有評論和想法;)</p>
P粉151466081
P粉151466081

全部回覆(1)
P粉550323338

你想做的事情真的很難。同步這樣的設備很困難。當您不擁有和控制硬體時,這樣做幾乎是不可能的。坦白說,我認為你永遠不會得到你想要的。

時間戳永遠不會起作用。其一,這些設備不會都有相同的時間。他們都會稍微偏離。您的下一個想法是從中央來源(例如您的伺服器)向他們發送時間。問題在於,向每個設備發送資料將花費不同的、隨機的時間。您可以嘗試透過預先計算十幾個資料包的往返時間來猜測延遲,但這仍然是一個猜測,對於下一個資料包可能不準確。 NTP 有助於使裝置的時間接近相同時間,但沒有達到您想要的精確度。

即使它確實達到了您想要的準確性 - Android 也不是即時作業系統。 iPhone 則不然。即使您將鬧鐘設為 12:00:00,它也不會恰好在 12:00:00.000 觸發。在那之後的一段時間,當作業系統有空閒時間、空閒核心並且認為您的應用程式是最重要的調度應用程式時,它將觸發。這可能需要幾百毫秒。有些作業系統可以為您帶來您想要的承諾。它們被稱為即時作業系統,通常用於不會故障的嵌入式設備,例如醫療設備和昂貴機器的控制器。它們是一種與消費性設備所使用的完全不同的作業系統編寫方法。

我真的建議重新考慮您的需求並更現實地對待它們。有些技術可以讓您得到您想要的東西,但不能透過網路在消費者作業系統上的隨機硬體上獲得。

另外,如果你想這樣做 - 我真的不建議使用 React Native,它以垃圾收集語言運行解釋器,並且具有非常隨機的計時。您至少需要用 C 語言編寫啟動器,因為這是最可預測的方法。

但實際上,請重新考慮您的需求。為什麼需要在 50 毫秒內啟動?當您透過網路做事時,如果人們有一秒鐘不同步,這真的很重要嗎?

熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板