उपयोग किया गया
NodeJS, सॉकेट.आईओ
मुसीबत
कल्पना करें कि Socket.io के माध्यम से ऐप से जुड़े 2 उपयोगकर्ता U1 & U2 हैं । एल्गोरिथ्म निम्नलिखित है:
- U1 पूरी तरह से इंटरनेट कनेक्शन खो देता है (उदा। इंटरनेट बंद कर देता है)
- U2 U1 को एक संदेश भेजता है ।
- U1 संदेश अभी तक प्राप्त नहीं करता है, क्योंकि इंटरनेट नीचे है
- सर्वर U1 वियोग का पता दिल की धड़कन के समय से लगाता है
- U1 सॉकेट के लिए फिर से जुड़ता है
- U1 कभी भी U2 से संदेश प्राप्त नहीं करता है - यह मुझे लगता है कि चरण 4 पर खो गया है।
संभव व्याख्या
मुझे लगता है कि मैं समझता हूं कि ऐसा क्यों होता है:
- चरण 4 पर सर्वर सॉकेट आवृत्ति और संदेशों की कतार U1 को भी मारता है
- इसके अलावा चरण 5 यू 1 और सर्वर नया कनेक्शन बनाते हैं (इसका पुन: उपयोग नहीं किया जाता है), इसलिए भले ही संदेश अभी भी पंक्तिबद्ध हो, पिछला कनेक्शन वैसे भी खो जाता है।
मदद की ज़रूरत है
मैं इस तरह के डेटा हानि को कैसे रोक सकता हूं? मुझे सुनने के लिए उपयोग करना है, क्योंकि मैं लोगों को हमेशा के लिए ऐप में नहीं लटकाता हूं। इसके अलावा, मुझे अभी भी फिर से कनेक्ट करने की संभावना देनी चाहिए, क्योंकि जब मैं ऐप का नया संस्करण तैनात करता हूं तो मुझे शून्य डाउनटाइम चाहिए।
PS जिस चीज को मैं "संदेश" कहता हूं वह केवल एक पाठ संदेश नहीं है जिसे मैं डेटाबेस में संग्रहीत कर सकता हूं, बल्कि मूल्यवान सिस्टम संदेश, जिसे डिलीवरी की गारंटी दी जानी चाहिए, या यूआई शिकंजा।
धन्यवाद!
जोड़ 1
मेरे पास पहले से ही उपयोगकर्ता खाता प्रणाली है। इसके अलावा, मेरा आवेदन पहले से ही जटिल है। ऑफ़लाइन / ऑनलाइन स्टेटस जोड़ने से मदद नहीं मिलेगी, क्योंकि मेरे पास पहले से ही इस तरह का सामान है। समस्या अलग है।
चरण 2 देखें। इस चरण पर हम तकनीकी रूप से यह नहीं कह सकते हैं कि क्या यू 1 ऑफ़लाइन हो जाता है , वह केवल 2 सेकंड के लिए कनेक्शन खो देता है, शायद खराब इंटरनेट के कारण। तो U2 उसे एक संदेश भेजता है, लेकिन U1 इसे प्राप्त नहीं करता है क्योंकि इंटरनेट अभी भी उसके लिए नीचे है (चरण 3)। ऑफ़लाइन उपयोगकर्ताओं का पता लगाने के लिए चरण 4 की आवश्यकता है, जो कहते हैं कि, टाइमआउट 60 सेकंड है। आखिरकार U1 के लिए एक और 10 सेकंड के इंटरनेट कनेक्शन में है और वह सॉकेट के लिए फिर से जुड़ता है। लेकिन U2 का संदेश अंतरिक्ष में खो गया है क्योंकि सर्वर U1 पर टाइमआउट द्वारा डिस्कनेक्ट कर दिया गया था।
यही समस्या है, मैं 100% डिलीवरी नहीं करता।
उपाय
- यादृच्छिक एमिट द्वारा पहचाने गए {} उपयोगकर्ता में एक एमिट (इमिट नाम और डेटा) लीजिए। एमिट भेजें
- ग्राहक पक्ष पर उत्सर्जन की पुष्टि करें (emitID के साथ सर्वर पर वापस भेजें)
- यदि पुष्टि की गई है - ऑब्जेक्ट को {} से हटाकर emitID द्वारा पहचाना गया है
- यदि उपयोगकर्ता पुन: कनेक्ट हो गया है - इस उपयोगकर्ता के लिए {} की जाँच करें और इसके माध्यम से लूप करें {{प्रत्येक वस्तु में चरण 1 को निष्पादित करने के लिए।
- जब डिस्कनेक्ट या / और कनेक्ट फ्लश {} यदि आवश्यक हो तो उपयोगकर्ता के लिए
// Server
const pendingEmits = {};
socket.on('reconnection', () => resendAllPendingLimits);
socket.on('confirm', (emitID) => { delete(pendingEmits[emitID]); });
// Client
socket.on('something', () => {
socket.emit('confirm', emitID);
});
समाधान 2 (थोड़े)
1 फरवरी 2020 को जोड़ा गया।
हालांकि यह वेबसोकेट के लिए वास्तव में एक समाधान नहीं है, फिर भी कोई इसे काम में ले सकता है। हम Websockets से SSE + Ajax में चले गए। SSE आपको एक ग्राहक से लगातार टीसीपी कनेक्शन रखने और रियलटाइम में सर्वर से संदेश प्राप्त करने के लिए कनेक्ट करने की अनुमति देता है। क्लाइंट से सर्वर पर संदेश भेजने के लिए - बस अजाक्स का उपयोग करें। विलंबता और ओवरहेड जैसे नुकसान हैं, लेकिन एसएसई विश्वसनीयता की गारंटी देता है क्योंकि यह टीसीपी कनेक्शन है।
चूंकि हम एक्सप्रेस का उपयोग करते हैं, इसलिए हम इस लाइब्रेरी का उपयोग SSE https://github.com/dpskvn/express-sse के लिए करते हैं , लेकिन आप उसे फिट कर सकते हैं।
SSE IE और अधिकांश एज संस्करणों में समर्थित नहीं है, इसलिए आपको एक पॉलीफ़िल की आवश्यकता होगी: https://github.com/Yaffle/EventSource ।