2013-06-21 5 views
8

स्थिति:
मैं एक php स्क्रिप्ट के लिए अनुरोध भेजने के लिए $ .ajax() POST का उपयोग कर रहा हूं जो 400,000-500,000 लाइनों को एक डीबी में सम्मिलित करता है। इसमें लगातार 3.5 - 4 मिनट लगते हैं। (इस समय के दौरान, अनुरोध पेंडिंग है)।

समस्या:
मुझे पृष्ठ पर प्रगति दिखाने के लिए कुछ तरीका चाहिए। (जैसे की %)। मैंने एक सेट में $ .ajax() का उपयोग करने की कोशिश की, अंतराल जो हर 5 सेकंड या उससे भी अधिक की जांच करता है, लेकिन वे निर्माण करते हैं और सभी तब आते हैं जब पहला (लंबा) $ .ajax() समाप्त हो जाता है।

प्रश्न:
डिफ़ॉल्ट रूप से $ .ajax() async नहीं है? क्या इसका मतलब किसी भी क्रम में और किसी भी समय अनुरोध नहीं किया जा सकता है, और प्रतिक्रिया किसी भी क्रम में और किसी भी समय प्राप्त की जानी चाहिए ?? क्या यह एसिंक के साथ कुछ भी करने के लिए है? क्या एक अनुरोध से समय-समय पर 'अर्ध-प्रतिक्रिया' वापस भेजने का कोई तरीका है? या लंबित अनुरोध/प्रतिक्रिया होने पर मैं अनुरोध/प्रतिक्रिया भेज और प्राप्त नहीं कर सकता हूं? (नीचे भयानक चित्र देखें)

अग्रिम धन्यवाद !!!

multiple requests http://kshaneb.com/reqres.png

+2

ग्राफ के लिए +1 के साथ परीक्षण किया गया। :) क्या आपने अपने डेटा को तोड़ने पर विचार किया था, यानी प्रत्येक 10k पंक्तियों के अलग-अलग आवश्यकताएं भेज रहे थे? स्पष्टीकरण के लिए –

+1

+1। क्या आपने एसिंक सच के साथ प्रयास किया .. – sathish

+0

मैं ऊपर ज़ोल्ल्ट से सहमत हूं, अपने डेटा को कई छोटे अनुरोधों में छेड़छाड़ करने पर विचार करें जो आपको तेजी से प्रतिक्रिया दे सकता है, आप भी अनुरोधों के पूरा होने के% आधार की गणना कर सकते हैं। एकल अनुरोध में बड़े डेटा को अपलोड करना, हालांकि एसिंक, धीमे प्रदर्शन के परिणामस्वरूप भी होगा। –

उत्तर

1

इसके बजाय एक ajax पोस्ट करने के आप एक iframe पर पोस्ट और php वृद्धिशील उत्पादन पैदा करते हैं और flush कमांड के साथ भेज देते हैं हो सकता है।

// send a hash mark for every 1000 inserts 
$a = 0; 
while ($rec = getDataForNextInsert()){ 
     $a++; 
     // do insert 
     if ($a%1000 == 0) { echo '#'; flush(); } 
} 

फिर भी अंतिम उपयोगकर्ता के लिए एक सुंदर प्रदर्शन प्रदान करने के लिए आईफ्रेम की सामग्री को मतदान करना संभव होगा।

2

आशा इस मदद करता है

$(function() 
    { 
     var statusElement = $("#status"); 

     // this function will run each 1000 ms until stopped with clearInterval() 
     var i = setInterval(function() 
     { 
      $.ajax(
      { 
       success: function (json) 
       { 
        // progress from 1-100 
        statusElement.text(json.progress + "%"); 

        // when the worker process is done (reached 100%), stop execution 
        if (json.progress == 100) clearInterval(i); 
       }, 

       error: function() 
       { 
        // on error, stop execution 
        clearInterval(i); 
       } 
      }); 
     }, 1000); 
    }); 
+0

आपके AJAX कॉल में कोई यूआरएल नहीं है। शायद यह चाहिए। –

7

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

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

समाधान: स्क्रिप्ट पूर्ण होने तक सत्र बंद हो जाता है या सत्र मैन्युअल रूप से बंद हो जाता है। अवरुद्ध करने से कई PHP अनुरोधों (जिन्हें $ _SESSION डेटा की आवश्यकता है) को रोकने के लिए, आप सत्र शुरू कर सकते हैं और फिर सत्र बंद कर सकते हैं। यह सत्र फ़ाइल अनलॉक करेगा और प्रारंभिक अनुरोध पूरा होने से पहले शेष अनुरोधों को जारी रखने की अनुमति देगा।यहाँ

और जानकारी: http://konrness.com/php5/how-to-prevent-blocking-php-requests/

+2

[यह बेहतर होगा] (http://meta.stackexchange.com/q/8259) यहां उत्तर के आवश्यक हिस्सों को शामिल करने के लिए (न केवल कारण, बल्कि समाधान), और संदर्भ के लिए लिंक प्रदान करें। –

+0

धन्यवाद @optimistiks। जैसा कि मैंने इस आलेख में सुझाव दिया है, मैं session_write_close() का उपयोग कर रहा हूं इससे पहले कि मैं अपने PHP स्क्रिप्ट का समय लेने वाला हिस्सा चला रहा हूं और ... यह काम कर रहा है! वैसे भी स्थानीयहोस्ट पर। मुझे यकीन है कि जब मैं इसे सर्वर पर धक्का दूंगा तो नए मुद्दे होंगे। एक बार फिर धन्यवाद! – ksb86

1

मुझे आशा है कि इस बात के लिए आप

सबसे पहले उपयोगी होगा, आप

@apache_setenv('no-gzip', 1); 
@ini_set('zlib.output_compression', 0); 
@ini_set('implicit_flush', 1); 
for ($i = 0; $i < ob_get_level(); $i++) { ob_end_flush(); } 
ob_implicit_flush(1); 

फिर अपने PHP स्क्रिप्ट में उत्पादन बफर अक्षम करने की आवश्यकता प्रक्रिया के दौरान आपको PHP से अपनी प्रगति को प्रतिबिंबित करने की आवश्यकता है, कुछ ऐसा:

for($i=0;$i < 20;$i++){ 
    echo ($i > 0 ? "#":"").($i/20*100); 
    sleep(1); 
} 

फिर, जावास्क्रिप्ट में आपको xhr तैयारस्टेट परिवर्तन ईवेंट सुनने की आवश्यकता है और जब ऐसा होता है, तो प्रतिक्रिया पाठ को पार्स करें और प्रगति को दिखाएं जैसा आप चाहते हैं।

घटना के लिए सुन रहा:

$.ajaxPrefilter(function(options, _, jqXHR) { 
       if (options.onreadystatechange) { 
        var xhrFactory = options.xhr; 
        options.xhr = function() { 
         var xhr = xhrFactory.apply(this, arguments); 
         function handler() { 
          options.onreadystatechange(xhr, jqXHR); 
         } 
         if (xhr.addEventListener) { 
          xhr.addEventListener("readystatechange", handler, false); 
         } else { 
          setTimeout(function() { 
           var internal = xhr.onreadystatechange; 
           if (internal) { 
            xhr.onreadystatechange = function() { 
             handler(); 
             internal.apply(this, arguments); 
            }; 
           } 
          }, 0); 
         } 
         return xhr; 
        }; 
       } 
      }); 

और ajax अनुरोध का नमूना:

$.ajax({ 
        url: "test.php", 
        cache: false, 
        onreadystatechange: function(xhr) { 
         res = xhr.responseText.split("#"); 
         $("#id").html(res[res.length-1] + "% done<br/>"); 
        }     
       }).done(function(data) { 
         $("#id").append("all done!</br>"); 
        }); 
      }); 

jQuery 1.5+

+0

यह मेरी मदद की, धन्यवाद। क्या आप इन कोडों के साथ क्रॉसब्रोसर संगतता के बारे में कोई समस्या जानते हैं? – littlealien

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