2013-01-07 15 views
7

मैंने एक लंबे मतदान कनेक्शन को लागू किया है ताकि मुझे टॉमकैट वेब सर्वर और फ्रंटएंड पर मानक जावास्क्रिप्ट का उपयोग करके सर्वर-साइड पुश (धूमकेतु) करने की अनुमति मिल सके। कनेक्शन जारी रखने के लिए, मेरे पास एक सरल रख-रखाव लूप है जो अंतिम बार पूरा होने/विफल होने पर एक नया अनुरोध शुरू करता है।लंबे मतदान के साथ समस्याएं XMLHttpRequests और intermittent नेटवर्क कनेक्शन

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

यहाँ अनुरोध उद्देश्य यह है कि मैं क्रोम में देखते हैं जब यह इस मूक मौत मर जाता है:

request: XMLHttpRequest 
    onabort: function() 
    onerror: function() 
    onload: null 
    onloadend: null 
    onloadstart: null 
    onprogress: null 
    onreadystatechange: function() 
    readyState: 1 
    response: "" 
    responseText: "" 
    responseType: "" 
    responseXML: null 
    status: [Exception: DOMException] 
    statusText: [Exception: DOMException] 
    upload: XMLHttpRequestUpload 
    withCredentials: false 

मैं तीन श्रोताओं है (onabort, onerror, onreadystatechange) सेटअप संदेश सचेत करने के लिए अगर वे कभी निकाल दिया, लेकिन जब भी मैं सर्वर से अपना कनेक्शन लेता हूं तब मुझे कुछ भी नहीं मिलता है। यहाँ कैसे मैं अनुरोध बनाने हूँ:

var request = new XMLHttpRequest(); 

//url is just the url to my servlet to handle this 
request.open("GET", url, true); 

//handlestatechange is just my standard handling code 
//that I've put an alert at the top of 
request.onreadystatechange = handleStateChange; 

request.onerror = function() 
{ 
    alert("We encountered an error"); 
} 

request.onabort = function() 
{ 
    alert("I've had an abortion"); 
} 

request.send(null); 

यह इस तरह लगता है एक सुंदर मानक स्थिति होगी, लेकिन मैं कैसे एक लंबे मतदान कनेक्शन वियोग की इस तरह से उबरने के लिए अनुमति देने के लिए पर कोई बातचीत नहीं देखा है ।

क्या मैं कुछ गलत कर रहा हूं? क्या इस मुद्दे को खारिज करने वाले लंबे मतदान/धूमकेतु करने के लिए कुछ और मानक दृष्टिकोण है?

इस के साथ किसी भी मदद की सराहना की जाएगी, धन्यवाद

उत्तर

2

मेरा मानना ​​है कि सबसे अच्छा तरीका यह संभाल करने के लिए कुछ समय के लिए लंबे समय से चुनाव अनुरोध की अवधि सीमित करने के लिए है, T (जैसे 60 सेकंड एक नहीं अनुचित है मान), और उसके बाद स्थगित राज्यों का पता लगाने के लिए क्लाइंट में टाइमआउट का उपयोग करें। आदर्श रूप से आप इसे एक्सएचआर timeout संपत्ति के साथ करेंगे, लेकिन डब्ल्यू 3 सी स्पेक में होने के बावजूद it isn't supported x-browser। इस प्रकार, आप setTimeout और xhr.abort() का उपयोग करके अपना स्वयं का समर्थन लागू करना चाहेंगे।

ग्राहक तब मान सकते हैं कि यदि उन्हें टी सेकंड में प्रतिक्रिया नहीं मिलती है तो कनेक्शन बंद हो गया है और वर्तमान अनुरोध को रद्द करने और पुनः कनेक्ट करने का प्रयास करना उचित है।

यह उचित रूप से अच्छी तरह से काम करता है, लेकिन इसका मतलब यह है कि क्लाइंट का कनेक्शन रुक गया है (टी सेकेंड तक) का पता लगाने में कुछ विलंबता है। लंबे मतदान के अनुरोधों के साथ मुझे नहीं पता कि इसके बारे में बहुत कुछ करना है। यदि आपको वास्तव में एक बेहतर समाधान की आवश्यकता है, तो हो सकता है कि आप streaming comet कनेक्शन देखना चाहें जो दिल की धड़कन संदेश या WebSockets वापस भेजता है।

यह आसान जवाब है। दुर्भाग्यवश यह अजीब किनारे के मामलों के सभी प्रकार के साथ एक गैर-मामूली समस्या साबित हुई। उदाहरण के लिए, आप कनेक्शन टाइमआउट के साथ प्रॉक्सी सर्वर की देखभाल कर सकते हैं या नहीं, या विभिन्न तरीकों से आपके उपयोगकर्ताओं के कंप्यूटर पर डिफ़ॉल्ट टीसीपी टाइमआउट बदला जा सकता है। यही कारण है कि हमने Socket.IO जैसे ढांचे को देखा है जो इस उग्रता को बहुत छिपाते हैं।

पीएस शायद यह ध्यान देने योग्य है कि आप navigator.onLine के माध्यम से कुछ ब्राउज़रों में ऑनलाइन स्थिति की निगरानी कर सकते हैं, लेकिन यह poorly supported है। क्रोम में यह एकमात्र ब्राउज़र वास्तव में सही तरीके से व्यवहार करता है। एकमात्र चीज़ यह वास्तव में आपको बताती है कि यदि उपयोगकर्ता किसी कारण से ऑफ़लाइन होने के लिए जाना जाता है।यह आपको नहीं बता सकता कि उनके पास एक कार्यकारी कनेक्शन है।

+0

उत्तर के लिए धन्यवाद। यह समाधानों का सेट कम या कम है जिसे मैंने अब तक देखा था। मुझे लगता है कि मुझे संभवतः टाइमआउट मूल्य को कम करने और कनेक्टिविटी सुनिश्चित करने के लिए नियमित दिल की धड़कन का उपयोग करने के आपके विचार को पसंद है। मैंने पहले xhr.abort() का उपयोग करने का प्रयास किया है, लेकिन टॉमकैट साइड पर कुछ वास्तव में अजीब बग पाए गए हैं ([एपॉलवाइट सीपीयू को 100% तक बढ़ा सकता है और जब तक मैं टॉमकैट को पुनरारंभ नहीं करता तब तक ठीक नहीं होगा] (https: // मुद्दों। apache.org/jira/browse/DIRMINA-678)) – dallas

संबंधित मुद्दे