다중 장치(휴대폰) 동기화 - React Native
P粉151466081
P粉151466081 2023-09-05 11:58:38
0
1
702
<p>모든 사용자의 모바일 장치에서 동시에 실행되는 Lightshow를 만들려고 합니다(최대 2000-3000명의 사용자가 있을 수 있음). 모든 사용자는 인터넷(Wi-Fi 또는 모바일 데이터)을 사용합니다. FE에서는 구독을 위해 Apollo를 사용하는데 이는 정말 매력적입니다. </p> <p>하지만 문제는 사용자 A가 사용자 B보다 더 빨리 구독 이벤트를 얻을 수 있다는 것입니다. 이는 사용자 A가 사용자 B보다 먼저 게임을 시작한다는 것을 의미하는데, 이는 우리가 라이트쇼 아키텍처를 갖고 있고 사용자가 더 일찍 또는 나중에 시작할 수 없기 때문에 문제가 됩니다. 사용자로서 차이점을 즉시 확인할 수 있으며 좋아 보이지 않습니다. </p> <p>제가 본 바로는 지연 시간 차이가 최대 300ms에 이를 수 있다는 것입니다. Android(Xiaomi 9)와 iOS(iPhone11) 사이의 시간은 대부분 약 180ms+-입니다. 두 iOS 기기인 iPhone 11과 iPhone 13을 비교하면 그 차이는 약 50~100밀리초입니다. 이 차이를 없애거나 모든 장치에 대해 최소한 40-60ms로 줄이는 방법이 있습니까? </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;">'dayjs'에서 dayjs를 가져옵니다. 'react-native-ntp-client'에서 ntpClient를 가져옵니다. const LightshowScreen 내보내기: React.FC< LightshowScreenProps<'Lightshow'> > = ({경로}) => const {데이터, 로딩} = useSubscription(JOIN_LIGHTSHOW_SUBSCRIPTION, { 변수: {lightshowId: Route.params.lightshow.id}, }); useEffect(() => { const getServerTime = async (lightshowStartAt: 번호) => // 함수를 완료하는 데 충분한 시간을 제공하기 위해 시작을 10초 지연합니다. lightshowStartAt는 서버의 타임스탬프입니다. const lightshowStart = dayjs.unix(lightshowStartAt).add(10, 's'); ntpClient.getNetworkTime('time.cloudflare.com', 123, (오류, 날짜) => { if (오류) { console.error('연결할 수 없습니다', error); 반품; } console.log('NTP 클라이언트 날짜 - ', 날짜); // Mon Jul 08 2013 21:31:31 GMT+0200 (파리, 마드리드(heure d'été)) let ntpTime = dayjs(date); // ms 단위의 차이 const diff = lightshowStart.diff(ntpTime); // 이 시간 초과 후에는 모든 장치가 동시에 재생을 시작해야 합니다. setTimeout(() => { lightshowStartHandler(); }, 차이점); }); }; if (data & data?.joinLightshow.started) { const lightshowData = data.lightshow; getServerTime(lightshowData.startedAt); } }, [데이터]); useEffect(() => { if (data && data?.joinLightshow?.finished) { lightshowFinishHandler(); } }, [데이터]); 반품 ( <보기 스타일={style.container}> .... </보기> ); };</pre> <p>모든 의견과 생각에 감사드립니다.)</p>
P粉151466081
P粉151466081

모든 응답(1)
P粉550323338

하고 싶은 일이 정말 힘들어요. 이러한 장치를 동기화하는 것은 어렵습니다. 하드웨어를 소유하고 제어하지 않으면 이를 수행하는 것이 거의 불가능합니다. 솔직히 말해서, 나는 당신이 원하는 것을 결코 얻을 수 없을 것이라고 생각합니다.

타임스탬프는 작동하지 않습니다. 우선, 이러한 장치는 모두 동일한 타이밍을 갖지 않습니다. 모두 약간씩 떨어져 있을 것입니다. 다음 아이디어는 서버와 같은 중앙 소스에서 시간을 보내는 것입니다. 문제는 각 장치에 데이터를 전송하는 데 임의의 시간이 걸린다는 것입니다. 12개의 패킷에 대한 왕복 시간을 미리 계산하여 대기 시간을 추측할 수 있지만 이는 여전히 추측일 뿐이며 다음 패킷에서는 정확하지 않을 수 있습니다. NTP는 장치의 시간을 동일한 시간에 가깝게 유지하는 데 도움이 되지만 원하는 만큼 정확하지는 않습니다.

원하는 정확도를 달성하더라도 Android는 실시간 운영 체제가 아닙니다. iPhone에서는 그렇지 않습니다. 알람을 12:00:00으로 설정하더라도 정확히 12:00:00.000에 알람이 울리지는 않습니다. 그 후 언젠가 운영 체제에 유휴 시간, 유휴 코어가 있고 애플리케이션을 가장 중요한 예약 애플리케이션으로 간주할 때 실행됩니다. 이 작업에는 수백 밀리초가 걸릴 수 있습니다. 원하는 약속을 제공할 수 있는 운영 체제가 있습니다. 실시간 운영체제(Real-Time Operating System)로 알려진 이 운영체제는 의료 장비, 고가 기계용 컨트롤러 등 고장이 나지 않는 임베디드 장치에 자주 사용됩니다. 이는 소비자 장치에서 사용되는 운영 체제 작성과 완전히 다른 접근 방식입니다.

귀하의 요구 사항을 다시 생각하고 이에 대해 좀 더 현실적으로 생각하는 것이 좋습니다. 원하는 것을 얻을 수 있는 기술이 있지만 인터넷을 통한 소비자 운영 체제의 임의 하드웨어에서는 얻을 수 없습니다.

또한 이렇게 하고 싶다면 React Native를 사용하는 것을 별로 권장하지 않습니다. React Native는 가비지 수집 언어로 인터프리터를 실행하며 타이밍이 매우 무작위입니다. 가장 예측 가능한 접근 방식이므로 최소한 C로 런처를 작성하는 것이 좋습니다.

하지만 실제로는 귀하의 요구 사항을 재고해 보시기 바랍니다. 왜 50밀리초 내에 시작해야 합니까? 인터넷을 통해 작업할 때 사람들이 잠시 동기화되지 않는 것이 정말로 문제가 됩니까?

최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿