नेटवर्क क्लाइंट-सर्वर संदेश विनिमय और घड़ी तुल्यकालन मदद


10

मैं एक तेजी से पुस्तक भौतिकी खेल है कि एक टेबल हॉकी कर रहा हूँ। दो मैलेट और एक पक के साथ। खेल iphone / ipad पर चलता है और मैं GameCenter के माध्यम से मल्टीप्लेयर भाग कर रहा हूँ।

यह नेटवर्क सिस्टम कैसे काम करता है। क्लाइंट जो मैच को तारांकित करता है, उसे सर्वर के रूप में निपटाया जाएगा और जो मैच अनुरोध स्वीकार करता है वह क्लाइंट है।

'सर्वर' में भौतिकी चल रही है और प्रतिक्रिया तत्काल है और ग्राहक के पास भी अपनी भौतिकी चल रही है इसलिए यह संदेशों के आदान-प्रदान के बीच सहज है। मैं सर्वर के रूप में क्या करता हूं, क्या मैं क्लाइंट को अपना puck वेलोसिटी और मेरी पोजीशन भेजता हूं और क्लाइंट अपने puck वेलोसिटी / पोजिशन को सर्वर से सिंक करने के लिए एडजस्ट करता है। अन्यथा भौतिकी desynchronizes और इसे खराब कर देती है।

जब नेटवर्क विलंबता अच्छी होती है, तो 100 मिलीमीटर के परिणाम बहुत अच्छे होते हैं, मुझे क्लाइंट की तरफ एक स्मूथ खेलने योग्य गेम मिला और अजीब व्यवहार न्यूनतम है। समस्या तब होती है जब अंतराल 150 से 200 सेमी के आसपास होता है। उस स्थिति में, ऐसा होता है कि मेरे मुवक्किल ने पहले से ही एक किनारे और उल्टे दिशा की ओर इशारा किया था, लेकिन इसे सर्वर से एक विलंब संदेश प्राप्त होता है और यह गेंद के व्यवहार के लिए एक अजीब भावना पैदा करता है।

मैंने इसके बारे में कुछ बातें पढ़ी हैं:

पोंग नेटवर्क उदाहरण

सिंक्रनाइज़ेशन उदाहरण पर क्लिक करें

घड़ी सिंक पर विकिपीडिया

तो, मैं इसे कैसे हल कर सकता हूं? जहां तक ​​मैंने सबसे अच्छा विकल्प पढ़ा है कि मुझे सर्वर / क्लाइंट पर एक टाइमस्टैम्प के साथ एक घड़ी सिंक्रनाइज़ेशन करना है ताकि जब मुझे मेरी घड़ी से संबंधित संदेश देरी से मिलें, तो मैं तब अनदेखा करूं और ग्राहकों को अनुकरण करने दूं काम। क्या आप लोग इससे सहमत हैं? और चूंकि im अविश्वसनीय डेटा (UDP) भेज रहा है, इसलिए मुझे विलंबित संदेश या संदेश ऑर्डर से बाहर हो सकते हैं।

यदि वह सबसे अच्छा तरीका है, तो मैं घड़ी के सिंक्रनाइज़ेशन को कैसे लागू करूं। मैंने इस बारे में स्टेप्स पढ़े हैं कि मैं इसे कैसे समझ पाया।

इससे लगता है:

  1. क्लाइंट एक "समय अनुरोध" पैकेट पर वर्तमान स्थानीय समय टिकट और सर्वर को भेजता है।
  2. सर्वर द्वारा रिसीव करने पर, सर्वर स्टैम्प सर्वर-टाइम और रिटर्न देता है
  3. ग्राहक द्वारा प्राप्त होने पर, ग्राहक भेजे गए समय से वर्तमान समय को घटाता है और विलंबता की गणना करने के लिए दो से विभाजित करता है। यह क्लाइंट-सर्वर टाइम डेल्टा निर्धारित करने के लिए सर्वर समय से वर्तमान समय को घटाता है और सही घड़ी डेल्टा प्राप्त करने के लिए अर्ध-विलंबता में जोड़ता है। (अब तक यह अल्गोथिम एसएनटीपी के समान है)
  4. क्लाइंट हर बार कुछ सेकंड रोकते हुए, स्टेप्स को 3 पांच या अधिक बार 1 से दोहराता है। अंतरिम में अन्य ट्रैफ़िक की अनुमति दी जा सकती है, लेकिन सर्वोत्तम परिणामों के लिए इसे कम से कम किया जाना चाहिए। पैकेट प्राप्तियों के परिणाम सबसे कम-विलंबता क्रम में सबसे कम-विलंबता क्रम में संचित और क्रमबद्ध होते हैं। माध्यीय विलंबता इस आदेशित सूची से मध्य-बिंदु नमूना चुनकर निर्धारित की जाती है।
  5. माध्यिका से लगभग 1 मानक-विचलन से ऊपर के सभी नमूनों को छोड़ दिया जाता है और शेष नमूनों को एक अंकगणितीय माध्य का उपयोग करके औसत किया जाता है।

इस उदाहरण के बाद मेरे पास यह होगा:

चलो नाटक करते हैं खेल लोड हो गया है और मेरे ग्राहक का समय अभी 0 है, इसलिए मैं सर्वर को भेजता हूं कि मेरा समय 0 है।

संदेशों को सर्वर पर लाने के लिए 150ms लगते हैं लेकिन सर्वर की घड़ी पहले ही शुरू हो चुकी थी और क्लाइंट से 1 सेकंड आगे है। जब सर्वर को संदेश मिलता है तो समय होगा: 1.15 और उस समय को क्लाइंट को भेजता है, क्या हम अच्छे हैं? हमारे बहाने 150 लीटर पर स्थिर है दिखावा करते हैं।

अब ग्राहक समय 1.15 प्राप्त करता है और भेजे गए समय से वर्तमान समय को घटाता है और विलंबता की गणना करने के लिए दो से विभाजित करता है। विच है: 0.3 - 0 = 0.3 / 2 -> 150ms।

यह क्लाइंट-सर्वर टाइम डेल्टा निर्धारित करने के लिए सर्वर समय से वर्तमान समय को घटाता है और सही घड़ी डेल्टा प्राप्त करने के लिए अर्ध-विलंबता में जोड़ता है:
क्लाइंट समय: 0.3 सर्वर समय 1.15
0.3 - 1.15 = .85 + विलंबता (.15) = 1

यह कैसे सिंक्रनाइज़ है? मैं क्या खो रहा हूँ?

यह मल्टीप्लेयर और नेटवर्क अनुभव पर मेरा पहली बार है, इसलिए मैं थोड़ा भ्रमित हूं।

धन्यवाद।


अच्छा प्रश्न। क्या आप सही कर सकते हैं: 0.3 - 1.15 से 1.15 - 0.3 हो सकता है?
सियारन

जवाबों:


12

पोस्ट किया गया एल्गोरिथ्म सही था, लेकिन आपके उदाहरण में आप उस समय के बारे में भूल रहे हैं जो क्लाइंट को प्राप्त करने के लिए सर्वर पैकेट के लिए होता है, इसलिए:

Server time: 1
Client time: 0
Client sends 0 to server

... 150ms to get to server  (ping is 300! not 150ms in this case. Ping is round-trip)

Server time: 1.15
Client time: 0.15
Server receives packet and sends client 1.15

... 150ms to get back to client

Server time: 1.30
Client time: 0.30
Client receives 1.15 from server

अब जैसा कि आप देख सकते हैं, अगर क्लाइंट ने अपनी घड़ी को 1.15 में बदल दिया, तो यह सर्वर के पीछे 0.15 होगा, यही कारण है कि आपको पिंग (उर्फ राउंड ट्रिप टाइम [आरटीटी]) के लिए समायोजित करना होगा। यहां कई चरणों में पूर्ण डेल्टा समय गणना की गई है:

Server Time - Current Time + Ping / 2
= Server Time - Current Time + (Current Time - First Packet Time) / 2
= 1.15 (Perceived, not actual!) - 0.30 + (0.30 - 0.00) / 2
= 1.00

यह हमें 1.00 सेकंड का सही डेल्टा समय देता है


Im मिल रहा है, इसलिए मेरी क्लाइंट घड़ी 1.00 है और सर्वर 1.30 है। मेरे द्वारा सर्वर से संदेश प्राप्त करने के बाद मुझे यह जांचने के लिए पिंग को जोड़ना होगा कि क्या देर से संदेश या कुछ और है? एक और बात, क्या होगा यदि विलंबता बदल जाती है, क्या मुझे हर समय उन बछड़ों को करते रहना पड़ता है?
गमरियो

क्लाइंट के समय को सर्वर के समय के बराबर बनाने के लिए 1.00s का डेल्टा समय वर्तमान घड़ी में जोड़ा जाना है। लेटेंसी हमेशा बदलती रहती है, प्रत्येक पैकेट में थोड़ा अलग RTT होगा। एक खेल की तरह थोड़े समय की अवधि में, मैं इस समय को केवल एक बार सिंक करूँगा, क्लाइंट के पास एक बहुत अच्छा अनुमान होगा कि सर्वर का समय क्या है और दोनों घड़ियों को समान गति से आगे बढ़ना चाहिए। केवल एक अपवाद होगा यदि आपको एक पैकेट प्राप्त हुआ जो भविष्य से प्रतीत होता है। उस स्थिति में, 2 समाधान हैं: 1) एक नया समय सिंक करें। 2) अपनी घड़ी भविष्य घड़ी मैच के लिए अग्रिम
जॉन मैकडोनाल्ड

ठीक है, इस स्थिति को सिर्फ यह सुनिश्चित करने के लिए देखता हूं कि मुझे यह मिल गया है: सर्वर समय: 1s क्लाइंट समय: सर्वर सर्वर समय पर प्राप्त करने के लिए 150s: 1.15s क्लाइंट समय: 0.15s सर्वर क्लाइंट को प्राप्त करने के लिए क्लाइंट 1.15s 200ms भेजता है तो, मेरा पिंग अब 350ms है। क्या वो सही है? सर्वर समय: १.३५ ग्राहक समय: ०.३५ बछड़ों को करना: १.१५ - .३५ (०.३५ - ०.००) / २ अब मेरा डेल्टा = ० ९ If५ यदि मैं डेल्टा समय को जोड़ दें तो ० ९ 35५ मेरे पास हो जाता है। क्या यह सही है?
15emm में 15

@ गिलसन, यह सही है। यदि दो पैकेट के लिए विलंबता (लगभग गारंटी) अलग है, तो ग्राहक के डेल्टा समय की गणना सही नहीं होगी। ग्राहक के लिए हमेशा सही होने का कोई रास्ता नहीं है। प्रश्न में वर्णित एल्गोरिथ्म में, डेल्टा समय की गणना कई बार की गई थी और इन परिणामों को चुनने और औसत करने के लिए एक विधि थी। कई बार सिंक तरीके कुछ इस तरह करेंगे, लेकिन वे आमतौर पर स्टॉक एक्सचेंजों के लिए व्यापार महत्वपूर्ण और लंबे समय तक चलने वाले सर्वर के लिए होते हैं। समय की सटीकता के लिए आपको एक छोटे खेल की आवश्यकता होती है, मुझे लगता है कि यह ओवरकिल होगा।
जॉन मैकडोनाल्ड

@ गिलसन, जब तक क्लाइंट के पास सर्वर के समय का उचित अनुमान होता है और दोनों घड़ियां लगभग एक ही दर से आगे बढ़ती हैं, आपको किसी भी मुद्दे पर ध्यान नहीं देना चाहिए। जब क्लाइंट या सर्वर दूसरी तरफ कार्रवाई भेजता है, तो वे अपना स्थानीय समय भेज देंगे। प्राप्त होने पर, संदेश हमेशा अतीत में होना चाहिए और अतीत की घटना के रूप में व्याख्या करने की आवश्यकता होगी। इसका मतलब है कि आपको पैकेट में सभी जानकारी की आवश्यकता है, जैसे स्थान, वेग (परिमाण + दिशा) और समय। तब आप पक को वहां रख सकते हैं और फिर, और अतीत से वर्तमान तक पक को स्थानांतरित कर सकते हैं। मैं चैट btw में हूँ
जॉन मैकडॉनल्ड्स
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.