2013-09-01 4 views
6

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

(function poll(){ 
$.ajax({ url: "server", success: function(data){ 
    //update page based on data 

}, dataType: "json", complete: poll, timeout: 30000 }); 
})(); 

पाने के लिए लग रहे हैं न लेकिन यह कैसे संबंध यहाँ खुला रखा है। मैं समझता हूं कि सर्वर से प्रतिक्रिया मिलने के बाद "मतदान" फ़ंक्शन को फिर से निकाल दिया जाता है। लेकिन कनेक्शन कैसे खुला रहता है?

Edit1: - यह अगर किसी को भी समझा सकता है क्या वास्तव में समय-समाप्त होता यहाँ करने

+0

शायद कनेक्शन खुला नहीं रखा गया है .... – rene

+0

आप सर्वर को कनेक्शन बंद करने से कैसे रोकते हैं। अगर अनुरोध सर्वर पर भेजा जाता है, तो यह जवाब देगा और फिर कॉन स्वचालित रूप से बंद हो जाएगा – Rasmus

+0

@itamecodes: आप अपना सर्वर लिखते हैं ताकि जब तक इसका जवाब देने के लिए डेटा न हो तब तक इसका जवाब न दें। – Eric

उत्तर

7

क्लाइंट कनेक्शन को खोलने के लिए सर्वर को मजबूर नहीं कर सकता है। सर्वर बस कनेक्शन बंद नहीं कर रहा है। सर्वर को कुछ बिंदु पर कहना होगा "यह है, यहां कोई और सामग्री नहीं है, अलविदा"। लंबे मतदान में, सर्वर बस ऐसा नहीं करता है और क्लाइंट को अधिक डेटा के लिए इंतजार कर रहा है, जो अपडेट में आने के साथ थोड़ा कम हो जाता है। यह लंबे मतदान है।

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

+0

मुझे लगता है कि मुझे अब मिल गया है .. क्या आप कृपया कुछ कंकाल साझा कर सकते हैं थोड़ा अधिक स्पष्टता के लिए सर्वर कोड – Rasmus

+0

@itamecodes एक महत्वपूर्ण बात: सर्वर पक्ष के लिए आपको टाइमआउट द्वारा कनेक्शन को बंद न करने के लिए कॉन्फ़िगरेशन सेट करने की आवश्यकता है। – VisioN

+1

@itame एक साधारण नमूना 'जबकि होगा (! ($ डेटा = checkDatabaseForData())) नींद (1); $ डेटा गूंजें; '- यह इस बात पर निर्भर करता है कि आप सर्वर की ओर से कौन सी भाषा काम कर रहे हैं, नोड.जेएस जैसी एक घटना प्रणाली 'नींद' लूप की तुलना में बहुत अधिक सुरुचिपूर्ण होगी। – deceze

1

कनेक्शन हर समय खुला रखा नहीं है बहुत अच्छा होगा। जब सर्वर से प्रतिक्रिया प्राप्त होती है और कनेक्शन कनेक्शन बंद हो जाता है तो यह स्वचालित रूप से बंद हो जाता है। लंबे मतदान में सर्वर को तुरंत डेटा वापस नहीं भेजा जाना चाहिए। AJAX complete पर (जब सर्वर कनेक्शन बंद कर देता है) नया अनुरोध सर्वर पर भेजा जाता है, जो एक नया कनेक्शन फिर से खोलता है और नई प्रतिक्रिया के लिए लंबित रखना शुरू कर देता है।

जैसा कि उल्लेख किया गया था, लंबे मतदान प्रक्रिया को न केवल ग्राहक पक्ष द्वारा संभाला जाता है, बल्कि मुख्य रूप से सर्वर पक्ष द्वारा किया जाता है। और न केवल सर्वर स्क्रिप्ट (PHP के मामले में), बल्कि सर्वर द्वारा, जो "hanged" कनेक्शन को टाइमआउट द्वारा बंद नहीं करता है।

FWIW, WebSockets सर्वर पक्ष के साथ लगातार खोले गए कनेक्शन का उपयोग करें, जो कनेक्शन को बंद किए बिना डेटा प्राप्त करने और वापस भेजने के लिए संभव बनाता है।

+0

फिर यह कोड पारंपरिक मतदान से अलग कैसे है। जिस तरह से मैंने इस जवाब को कम नहीं किया है – Rasmus

+1

@itamecodes यह * एक पारंपरिक "लंबा मतदान" दृष्टिकोण है। – VisioN

+0

@ रasmस पारंपरिक मतदान = AJAX मतदान: अनुरोधित वेबपृष्ठ जावास्क्रिप्ट निष्पादित करता है जो * नियमित * अंतराल पर सर्वर से फ़ाइल का अनुरोध करता है (उदा। 0.5 सेकंड)। देखें -http: //stackoverflow.com/questions/11077857/what-are-long-polling-websockets-server-sent-events-sse-and-comet –

6

मुझे लगता है कि समझने में यह भ्रमित करने वाला क्या है कि चर्चा क्लाइंट-साइड प्रोग्रामिंग पर केंद्रित है।

लंबे समय तक मतदान सख्ती से क्लाइंट-साइड पैटर्न नहीं है, लेकिन वेब सर्वर को कनेक्शन को खोलने की आवश्यकता है।

पृष्ठभूमि: कुछ होता है या उपलब्ध होने पर ग्राहक वेब सर्वर द्वारा अधिसूचित होना चाहता है, उदाहरण के लिए, मुझे बताएं कि जब कोई नया ईमेल वापस नहीं जाता है और हर कुछ सेकंड पूछता है तो मुझे बताएं।

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

आप नहीं देखते हैं कि यह केवल उस कोड से कैसे काम करता है, क्योंकि नियमित अनुरोध से वास्तविक अंतर सर्वर पर किया जाता है।

जावास्क्रिप्ट सिर्फ नियमित अनुरोध करता है, लेकिन सर्वर को तुरंत अनुरोध का जवाब नहीं देना पड़ता है। अगर सर्वर के पास लौटने योग्य कुछ भी नहीं है (यानी वह परिवर्तन जो ब्राउज़र का इंतजार कर रहा है, अभी तक नहीं हुआ है), सर्वर बस प्रतीक्षा करता है जो कनेक्शन को खुला रखता है।

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

2

मैं कुछ डेटा परिणामों के साथ कुछ करना चाहता था जहां कुछ तुरंत वापस आएंगे लेकिन अंतिम कुछ परिणाम 10-15 सेकंड बाद वापस आ सकते हैं। मैं एक त्वरित छोटे jQuery हैक बनाया लेकिन यह थोड़े कर रहा है कि मैं क्या (अब भी अगर यह समझ में आता है यद्यपि इसका इस्तेमाल करने के बारे में सुनिश्चित नहीं) हैं:

(function($) { 
    if (typeof $ !== 'function') return; 
    $.longPull = function(args) { 
     var opts = $.extend({ method:'GET', onupdate:null, onerror:null, delimiter:'\n', timeout:0}, args || {}); 
     opts.index = 0; 
     var req = $.ajaxSettings.xhr(); 
     req.open(opts.method, opts.url, true); 
     req.timeout = opts.timeout; 
     req.onabort = opts.onabort || null; 
     req.onerror = opts.onerror || null; 
     req.onloadstart = opts.onloadstart || null; 
     req.onloadend = opts.onloadend || null; 
     req.ontimeout = opts.ontimeout || null; 
     req.onprogress = function(e) { 
      try { 
       var a = new String(e.srcElement.response).split(opts.delimiter); 
       for(var i=opts.index; i<a.length; i++) { 
        try { 
         var data = JSON.parse(a[i]); // may not be complete 
         if (typeof opts.onupdate==='function') opts.onupdate(data, i); 
         opts.index = i + 1; 
        } catch(fx){} 
       } 
      } 
      catch(e){} 
     }; 
     req.send(opts.data || null); 
    }; 
})(jQuery); 

मोटे तौर पर अपरीक्षित लेकिन यह है कि तुम क्या मन में था करने के लिए लग रहा था। मैं तरीके यह गलत हो सकता है के सभी प्रकार के बारे में सोच सकता है, हालांकि ;-)

$.longPull({ url: 'http://localhost:61873/Test', onupdate: function(data) { console.log(data); }}); 
2

अनुरोध अनुसार, यहाँ कुछ छद्म NodeJS कोड है:

function respond_to_client(res,session,cnt) 
{ 
    //context: res is the object we use to respond to the client 
    //session: just some info about the client, irrelevant here 
    //cnt: initially 0 

    //nothing to tell the client, let's long poll. 
    if (nothing_to_send(res,session)) 
    { 
     if (cnt<MAX_LONG_POLL_TIME) 
     { 
      //call this function in 100 ms, increase the counter 
      setTimeout(function(){respond_to_client(request_id,res,session,cnt+1)},100); 
     } 
     else 
     { 
      close_connection(res); 
      //Counter too high. 
      //we have nothing to send and we kept the connection for too long, 
      //close it. The client will open another. 
     } 
    } 
    else 
    { 
     send_what_we_have(res); 
     close_connection(res); 
     //the client will consume the data we sent, 
     //then quickly send another request. 
    } 

    return; 

} 
1

मुझे लगता है कि कोई भी ठीक से समझाने हम क्यों कोड में टाइमआउट की आवश्यकता है। JQuery अजाक्स दस्तावेज़ों से:

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

टाइमआउट विकल्प वास्तव में X सेकंड के लिए अगले निष्पादन में देरी नहीं करता है। यह केवल वर्तमान कॉल के लिए अधिकतम टाइमआउट सेट करता है। टाइमआउट सामान के बारे में अच्छा लेख - https://mashupweb.wordpress.com/2013/06/26/you-should-always-add-timeout-to-you-ajax-call-in-jquery/

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