2012-10-08 24 views
7

मैं अपने Spring-MVC Web App में लंबे मतदान को लागू करने की कोशिश कर रहा हूं लेकिन यह मेरे ब्राउज़र को फ्रीज करता है और 4-5 के बाद अन्य अनुरोध AJAX अनुरोध जारी रखता है। मेरे पास कोई संकेत नहीं है कि यहां मेरा प्रासंगिक कोड है ।लंबे मतदान से ब्राउज़र को फ्रीज किया जाता है और अन्य AJAX अनुरोध को अवरुद्ध करता है

नियंत्रक विधि: (सर्वर साइड): -

@Asynchronous 
    @RequestMapping("/notify") 
    public @ResponseBody 
    Events notifyEvent(HttpServletRequest request) { 
     Events events = null; 
     try { 
      events = (Events) request.getSession(false).getServletContext().getAttribute("events"); 
      System.out.println("Request Came from" + ((com.hcdc.coedp.safe.domain.User) request.getSession(false).getAttribute(Constants.KEY_LOGGED_IN_USER)).getLoginId()); 
      if (!events.getTypeOfEvents().isEmpty()) { 
       System.out.println("Removing older entries"); 
       events.getTypeOfEvents().clear(); 
      } 
      while (!events.isHappend()) { 
       //Waiting for event to happen. 
      } 
      events = Events.getInstance(); 
      events.setHappend(false); 
      request.getSession(false).getServletContext().setAttribute("events", events); 

     }catch (Exception e) { 
      e.printStackTrace(); 
     } 
     return events; 
    } 

लंबे समय से मतदान लिपि (क्लाइंट साइड): -

$(document).ready(function() { 
        $.ajaxSetup({ 
         async:true//set a global ajax requests as asynchronus 
        }); 
        alert('Handler for .onload() called.'); 
        waitForMsg(); 

       }); 
       function waitForMsg(){ 

        xhr= $.ajax({ 
         type: "POST", 
         url: '<%=request.getContextPath()%>/notification/notify', 

         async: true, /* If set to non-async, browser shows page as "Loading.."*/ 
         cache: false, 
         timeout:50000, /* Timeout in ms */ 
         global:false, 
         success: function(data){ /* called when request to notifier completes */ 
          /* Doing smthing with response **/ 
          setTimeout(
          waitForMsg, /* Request next message */ 
          1000 /* ..after 1 seconds */ 
         ); 
         }, 
         error: function(XMLHttpRequest, textStatus, errorThrown){ 
          addmsg("error", textStatus + " (" + errorThrown + ")"); 
          setTimeout(
          waitForMsg, /* Try again after.. */ 
          15000); /* milliseconds (15seconds) */ 
         } 
        }); 
       }; 

अद्यतन:

function updateFeed(event, data) { 
       var f=eval(data); 
       alert(f.typeOfEvents.length); 
      } 

      function catchAll(event, data, type) { 
       console.log(data); 
       alert("error"); 
       console.log(type); 
      } 

      $.comet.connect('<%=request.getContextPath()%>/notification/notify'); 
      $(document).bind('feed.comet', updateFeed); 
      $(document).bind('.comet', catchAll); 

न तो अलर्ट बॉक्स पॉप अप .. :(

+0

मैं तुम्हें setTimeout बजाय setInterval उपयोग कर रहे हैं लगता है कि जरूरत नहीं है। जांचें [यह] (http://stackoverflow.com/questions/2696692/setinterval-vs-settimeout) – bhb

+0

मुझे लगता है कि इसे ठंडा करने की समस्या बिल्कुल सही नहीं है क्योंकि मैं बार-बार बार-बार विधि को कॉल करना चाहता हूं सफलता या त्रुटि)। –

+0

क्या आपको अपने फायरबग में कोई समस्या/त्रुटि दिखाई देती है। यदि सर्वर से आने वाला डेटा बहुत बड़ा है, तो यह ब्राउज़र को फ्रीज कर सकता है। – bhb

उत्तर

5

ऐसा लगता है कि आपके ब्राउज़र कोड में लूप होने पर आपके पास खाली है .. यह एक घटना के लिए प्रतीक्षा करने के लिए एक बहुत सीपीयू आक्रामक तरीका है।

यदि कोई घटना नहीं होती है तो क्लाइंट 50 सेकंड के वांछित टाइमआउट के बाद अनुरोध को मार देगा। लेकिन मुझे यकीन नहीं है कि सर्वर थ्रेड भी मारा गया है, या अगर यह हमेशा के लिए "whiles" (जब तक कोई घटना नहीं है)। अगला अनुरोध एक दूसरा सर्वर थ्रेड शुरू करेगा जो तब भी लूप में लटकता है। हो सकता है कि रिक्त होने की मात्रा सर्वर के लिए एक ओवरकिल है, ताकि यह किसी और अनुरोध को स्वीकार करना बंद कर दे। तो कुछ अनुरोधों के बाद (प्रत्येक ने एक अंतहीन सर्वर धागा ट्रिगर किया) क्लाइंट हमेशा एक नए अनुरोध पर इंतजार कर रहा है .. क्योंकि इसे सर्वर द्वारा नियंत्रित नहीं किया जा सकता है।

पुनश्च: सफलता पर आप 1 सेकंड प्रतीक्षा करने के लिए टिप्पणी की है, लेकिन 10000 (10 सेकंड) के लिए समय समाप्ति

+0

अपना मुद्दा प्राप्त करें यदि मैं कोड को लंबे समय तक मतदान करने के लिए कुछ कोड प्रदान करता हूं तो मैं इस समस्या को कैसे हल कर सकता हूं। धन्यवाद –

+0

बस यह जांचने के लिए कि क्या यह कारण है कि निम्न लूप के अंदर निम्न पंक्ति जोड़ें: 'Thread.currentThread()। नींद (1000); ' यह अन्य धागे को चलाने का मौका देने के लिए वर्तमान थ्रेड को सोएगा .. वांछित प्रतिक्रिया समय में नींद का समय समायोजित करें .. – lrsjng

+0

यह आदमी काम नहीं करेगा क्योंकि थ्रेड व्यवहार हमारे नियंत्रण में नहीं है, इसलिए यह प्रत्येक ग्राहक को अलग-अलग प्रतिक्रिया भेजेगा और हम यह भी सुनिश्चित नहीं कर सकते कि प्रत्येक ग्राहक एक ही प्रतिक्रिया प्राप्त कर लेता है। मैंने पहले छेड़छाड़ की कोशिश की है। –

2

मुझे इसी तरह की समस्या मिली है, मेरा ब्राउज़र AJAX अनुरोधों के साथ किसी भी तरह से फंस गया था। संकेत: इसके बजाय प्रतीक्षा करें ForMsg() सीधे, सेटटाइमआउट ("waitForMsg()", 10) का प्रयास करें। https://github.com/SeanOC/jquery.comet

सामान्य तौर पर, मैं जावास्क्रिप्ट धूमकेतु एपीआई कि सुंदर वापस आने के साथ ग्राहक/सर्वर पर उपलब्ध है, तो लंबे समय से मतदान करने के लिए वेब सॉकेट समर्थन कर सकते हैं के लिए खोज करेंगे:

+0

ने ब्राउज़र को काम करने की कोशिश नहीं की, अभी भी लोडिंग प्रतीक और फ्रीज दिखाएं। –

2

FYI करें, यहाँ एक परियोजना है कि आपकी मदद कर सकता है। एपीआई को सभी गॉरी विवरणों को संभालना चाहिए, जिससे आप एप्लिकेशन पर ध्यान केंद्रित कर सकते हैं। http://dojotoolkit.org/features/1.6/dojo-websocket

गुड लक:

यहाँ विषय पर एक पुराने डोजो लेख का लिंक है।

+0

आपके पहले लिंक में समाधान का प्रयास किया लेकिन काम नहीं कर रहा ... अपडेट में जोड़ा गया अपडेट। –

1

सेट यह इस हो सकता है: अपने waitForMsg समारोह में

 xhr= $.ajax({ (...) 

var xhr = (...) 

प्रयास करें हो सकता है कि आप वैश्विक वस्तु में XHR की घोषणा कर रहे हैं, इस प्रकार यह असंभव दो अलग-अलग अनुरोध का जवाब देना बना रही है।

2

आप jQuery आस्थगित का उपयोग कर व्यवहार के पुनर्लेखन के लिए कोशिश कर सकते हैं:

function setShortTimeout() { 
    setTimeout(waitForMsg, 1000); 
} 

function setLongTimeout() { 
    setTimeout(waitForMsg, 15000); 
} 

$(document).ready(function() { 
       $.ajaxSetup({ 
        async:true//set a global ajax requests as asynchronus 
       }); 
       alert('Handler for .onload() called.'); 
       $.when(waitForMsg()) 
        .done(successHandler, setShortTimeout) 
        .fail(errorHandler, setLongTimeout); 

      }); 

      function waitForMsg(){ 
       return $.ajax({ 
        type: "POST", 
        url: '<%=request.getContextPath()%>/notification/notify', 
        async: true, /* If set to non-async, browser shows page as "Loading.."*/ 
        cache: false, 
        timeout:50000, /* Timeout in ms */ 
        global:false 
       }); 
      }; 

errorHandler और successHandler अपनी सफलता हो जाएगा: और त्रुटि: कॉलबैक, जो मैं स्पष्टता के लिए छोड़ा जाता है, उनके setTimeout भाग के साथ हटा दिया (क्योंकि यह है अब deferred.done() और .fail() कॉलबैक का हिस्सा)।

अगर यह काम करता है तो मुझे बताएं।

2

मैं एक PHP डेवलपर हूं लेकिन मैं आपकी समस्या से मुलाकात की और यह वही व्यवहार हो सकता है। तो मैं आपको अपना 2 सेंट देता हूं और उम्मीद करता हूं कि यह आपकी मदद करेगा।

लाइन मुझे एक समस्या पर शक पड़ता है जो:

events = (Events) request.getSession(false).getServletContext().getAttribute("events"); 

पीएचपी में, सत्र फाइलों में जमा हो जाती है, और अगर हम एक PHP स्क्रिप्ट पर लंबे समय से मतदान कर रहे हैं, जबकि सत्र खुला है, हम मिलेंगे एक race condition समस्या।

सिद्धांत काफी सरल है:

  1. जब एक अनुरोध सत्र खुल जाता है, फ़ाइल जब तक सत्र बंद कर दिया है बंद है।
  2. यदि अन्य अनुरोध सर्वर पर आते हैं, तो वे पिछले अनुरोध से सत्र जारी होने तक लॉक हो जाएंगे।

लंबे मतदान के मामले में, यदि सत्र खोला गया है और जानकारी प्राप्त करने के बाद ही बंद नहीं किया गया है (कम से कम, घटनाओं की प्रतीक्षा करने से पहले), सभी अनुरोध अभी लॉक हैं, आप कहीं और नहीं जा सकते वेबसाइट यदि आप अन्य पृष्ठों पर सत्र का उपयोग कर रहे हैं। यहां तक ​​कि यदि आप एक नया टैब खोलते हैं, क्योंकि एक ब्राउज़र के लिए केवल एक सत्र होता है, तो आप लॉक हो जाते हैं।

+0

मैं ऐसा इसलिए कर रहा हूं क्योंकि मैं प्रत्येक उपयोगकर्ता ब्राउज़र पर एक ही घटना अधिसूचना को प्रतिबिंबित करना चाहता हूं, इसलिए सबसे अच्छा दायरा मुझे लगता है संदर्भ। लेकिन मैं ' यह आपके द्वारा प्रस्तावित किए गए प्रयासों को आज़माएगा। लेकिन php में session_write_close है, मुझे नहीं लगता कि जावा में ऐसी चीज है। –

9

लगता है जैसे आप अनुभव सत्र फ़ाइल ताला

पीएचपी

लिए

उपयोग session_write_close() जब आप सत्र मूल्य

+0

वास्तव में ओप ने क्या पूछा नहीं, लेकिन ऊपर उठाया क्योंकि यह वही था जो मैं ढूंढ रहा था – emerino