WebSocket को सही ढंग से बंद करना (HTML5, जावास्क्रिप्ट)


127

मैं HTML5 WebSockets के साथ खेल रहा हूँ। मैं सोच रहा था, मैं इनायत से कनेक्शन कैसे बंद करूं? जैसे, यदि उपयोगकर्ता पृष्ठ को ताज़ा करता है, या केवल ब्राउज़र बंद करता है, तो क्या होता है?

एक अजीब व्यवहार होता है जब कोई उपयोगकर्ता केवल कॉल किए बिना पृष्ठ को रीफ्रेश करता है websocket.close()- जब वे रिफ्रेश होने के बाद वापस आते हैं तो यह websocket.oncloseईवेंट को हिट करेगा ।

जवाबों:


110

प्रोटोकॉल युक्ति v76 के अनुसार (वर्तमान समर्थन लागू करने वाला वह ब्राउज़र है):

कनेक्शन को सफाई से बंद करने के लिए, एक 0x00 बाइट के बाद केवल 0xFF बाइट वाले एक फ्रेम को एक सहकर्मी से यह पूछने के लिए भेजा जाता है कि दूसरा सहकर्मी कनेक्शन बंद करता है।

यदि आप एक सर्वर लिख रहे हैं, तो आपको सर्वर कनेक्शन को क्लाइंट कनेक्शन बंद करने के लिए एक करीबी फ्रेम भेजना सुनिश्चित करना चाहिए। सामान्य टीसीपी सॉकेट बंद करने की विधि कभी-कभी धीमी हो सकती है और यह सोचने के लिए अनुप्रयोगों का कारण बन सकती है कि कनेक्शन तब भी खुला है जब वह नहीं है।

जब आप पृष्ठ को बंद या पुनः लोड करते हैं तो ब्राउज़र को वास्तव में आपके लिए ऐसा करना चाहिए। हालाँकि, आप यह सुनिश्चित कर सकते हैं कि पहले से लोड किए गए ईवेंट को कैप्चर करके एक करीबी फ़्रेम भेजा गया है:

window.onbeforeunload = function() {
    websocket.onclose = function () {}; // disable onclose handler first
    websocket.close();
};

मुझे यकीन नहीं है कि पेज रीफ्रेश होने के बाद आपको एक ऑनक्लोज़ इवेंट कैसे मिल सकता है। पेज रीलोड होने के बाद वेबसोकेट ऑब्जेक्ट (ऑनक्लोजर हैंडलर के साथ) मौजूद नहीं रहेगा। यदि आप पेज लोड होते ही अपने पेज पर तुरंत एक वेबसर्केट कनेक्शन स्थापित करने का प्रयास कर रहे हैं, तो आप एक ऐसे मुद्दे पर चल रहे हैं, जहां सर्वर पुराने कनेक्शन के डिस्कनेक्ट होने के तुरंत बाद एक नया कनेक्शन मना कर रहा है (या ब्राउज़र तैयार नहीं है उस बिंदु पर कनेक्शन बनाने के लिए जिसे आप कनेक्ट करने का प्रयास कर रहे हैं) और आपको नई वेबसोकेट ऑब्जेक्ट के लिए एक ऑनक्लोज़ इवेंट मिल रहा है।


2
यह संभव है कि फ़ायरफ़ॉक्स में कनेक्शन अगले पेज लोड में लटका हुआ लगे। मुझे एक संदर्भ नहीं मिल रहा है लेकिन मुझे लगता है कि इस बारे में एक बग हो सकता है। दूसरी संभावना यह है कि इस oncloseघटना को अप्रत्याशित रूप से ट्रिगर किया जा सकता है, या शायद उद्देश्य पर, क्योंकि उपयोगकर्ता नेवीगेट्स / पृष्ठ को फिर से लोड किया गया है। मैंने एक प्रश्न पोस्ट किया है जिसमें पूछा गया है कि अपेक्षित व्यवहार क्या होना चाहिए, किस ब्राउज़र में यह सही है और हम ऑटो-पुन: कनेक्ट कैसे लागू करते हैं।
लेगेंटर

4
घटना के साथ इन समस्याओं पर विचार करेंonbeforeunload
artkoenig


35

इसकी बात यह है कि आज उपयोग किए जाने वाले वेबस्केट्स के 2 मुख्य प्रोटोकॉल संस्करण हैं। पुराना संस्करण जो [0x00][message][0xFF]प्रोटोकॉल का उपयोग करता है, और फिर Hybi स्वरूपित पैकेट का उपयोग कर नया संस्करण है

पुराने प्रोटोकॉल संस्करण का उपयोग ओपेरा और iPod / iPad / iPhones द्वारा किया जाता है, इसलिए यह वास्तव में महत्वपूर्ण है कि WebSockets सर्वर में पिछड़े संगतता को लागू किया जाता है। पुराने प्रोटोकॉल का उपयोग करने वाले इन ब्राउज़रों के साथ, मुझे पता चला कि पेज को रीफ्रेश करना, या पेज से दूर नेविगेट करना या ब्राउज़र को बंद करना, ब्राउज़र में सभी परिणाम स्वतः कनेक्शन बंद कर देते हैं। महान!!

हालांकि नए प्रोटोकॉल संस्करण (जैसे फ़ायरफ़ॉक्स, क्रोम और अंततः IE10) का उपयोग करने वाले ब्राउज़रों के साथ, केवल ब्राउज़र को बंद करने से ब्राउज़र स्वतः कनेक्शन बंद कर देगा। यह कहना है, यदि आप पृष्ठ को ताज़ा करते हैं, या पृष्ठ से दूर जाते हैं, तो ब्राउज़र स्वचालित रूप से कनेक्शन बंद नहीं करता है। हालांकि, ब्राउज़र क्या करता है, पहले बाइट (प्रोटो पहचान) 0x88(बेहतर डेटा फ्रेम के रूप में जाना जाता है ) के साथ सर्वर पर एक हाइबी पैकेट भेजा जाता है। एक बार जब सर्वर इस पैकेट को प्राप्त कर लेता है तो यह जबरदस्ती कनेक्शन को बंद कर सकता है, यदि आप ऐसा चुनते हैं।


4
सर्वर पर एक व्यावहारिक उदाहरण कैसे इस हाइबी पैकेट का प्रबंधन करने के लिए?
अल्बानक्स

9
यह पागल लगता है कि यह कनेक्शन बंद नहीं करता है। WebSocket चर को पृष्ठ पुनः लोड करने पर मिटा दिया जाता है, इसलिए यदि इसे एक्सेस नहीं किया जा सकता है तो कनेक्शन खुला क्यों रहेगा? कनेक्शन का पुन: उपयोग करने से कोई मतलब नहीं होगा।
त्रिवेंको

@albanx नीचे मेरे जवाब की जाँच करें
आर्टकॉनिग

किसी भी कोड के नमूने कैसे वेबसैट क्लाइंट (यानी ब्राउज़र) से करीबी फ्रेम भेजने के लिए। मैं ws npm मॉड्यूल का उपयोग कर रहा हूं
शैक सैयद अली

3

जैसा कि बताया गया है Theoobe , कुछ ब्राउज़र स्वचालित रूप से वेबस्केट को बंद नहीं करते हैं। किसी भी "करीब ब्राउज़र विंडो" घटनाओं को संभालने की कोशिश मत करो क्लाइंट-साइड। वर्तमान में ऐसा करने का कोई विश्वसनीय तरीका नहीं है, यदि आप प्रमुख डेस्कटॉप और मोबाइल ब्राउज़र (जैसे onbeforeunloadमोबाइल सफारी में काम नहीं करेंगे) के समर्थन पर विचार करते हैं । मुझे इस समस्या को सर्वर-साइड हैंडल करने का अच्छा अनुभव था। जैसे यदि आप जावा ईई का उपयोग करते हैं, तो javax.websocket.Endpoint पर एक नज़र डालें , ब्राउज़र के आधार पर या तो OnCloseविधि या OnErrorविधि को बुलाया जाएगा यदि आप ब्राउज़र विंडो को बंद / पुनः लोड करते हैं।


1
मेरे मामले में, डेटा ट्रांसफर के दौरान कनेक्शन बंद हो रहा है, यह ओपेरा और आईओएस परिवार के ब्राउज़रों के मामले में अच्छा काम करता है। कृपया मेरी मदद करें .. मैं पिछले दो सप्ताह से इस मुद्दे से लड़ रहा हूँ। stackoverflow.com/q/30799814/2225439
मृग

2

वेब सॉकेट की करीबी विधि का उपयोग करके, जहां आप आवश्यकता के अनुसार कोई भी फ़ंक्शन लिख सकते हैं।

var connection = new WebSocket('ws://127.0.0.1:1337');
    connection.onclose = () => {
            console.log('Web Socket Connection Closed');
        };
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.