2012-07-02 22 views
8

मुझे यहां एक दुःस्वप्न का थोड़ा सा हिस्सा है, इसलिए किसी भी मदद की सराहना की जाएगी! सबसे पहले, मैं समझाऊंगा कि मैं क्या करने की कोशिश कर रहा हूं:jQuery लंबे मतदान (PHP सर्वर पक्ष के साथ)

मैं यहां वर्णित एक प्रणाली को लागू करने की कोशिश कर रहा हूं: https://stackoverflow.com/a/1086448/1034392 वाईआई फ्रेमवर्क का उपयोग करके मेरे स्थानीयहोस्ट एमएएमपी सर्वर पर। मेरे पास एक ऐसा फ़ंक्शन है जो जांचता है कि डीबी में कोई नई सूचनाएं हैं या नहीं - यदि ऐसा है, तो यह उन्हें पार्स करता है और जेसन उन्हें एन्कोड करता है। मेरे पास यह फ़ंक्शन हर 5 सेकेंड में थोड़ी देर लूप पर बुलाया गया है।

तो: करने के लिए/उपयोगकर्ता/unreadNotifications जा रहा से चलाता निम्नलिखित

Yii::log('test'); // to check it's getting called 

    $this->layout=false; 

    header('Content-Type: application/json'); 

    // LONG POLLING 
    while (Yii::app()->user->getNotifications() == null) { 
     sleep(5); 
    } 

    echo Yii::app()->user->getNotifications(); // prints out json if new notification 

    Yii::app()->end(); 

    return; 

यह ठीक काम करता है - ब्राउज़र में लिंक करने के लिए चला गया और json प्रतिक्रिया सत्यापित - सब अच्छा।

मैंने फिर काम करने के लिए सभी प्रकार की jQuery सामग्री की कोशिश की है ... काम करने के लिए मुझे एकमात्र तरीका $.ajax का उपयोग पोस्ट के साथ है, लेकिन केवल जब प्रतीक्षा प्रतीक्षा अधिसूचना है (तो कुछ जेसन वापस आ गया है)। $.get या $.post "निरस्त" हो जाता है (फ़ायरबग में प्रदर्शित) लेकिन यूआरएल कहा जाता है (क्योंकि मैं लॉग फ़ाइल को अद्यतन कर सकता हूं) - विषम।

मेरी मूल सेटअप $.get उपयोग कर रहा है:

 <script type="text/javascript"> 
      function notificationPoll() { 
       $.get('<?php echo Yii::app()->createUrl('user/unreadNotifications') ?>','', function(result) { 
        $.each(result.events, function(events) { 
         alert('New Notification!'); 
        }); 
        notificationPoll(); 
       }, 'json'); 
      } 
     </script> 

     <script type="text/javascript"> 
      $(document).ready(function() { 
       $.ajaxSetup({ 
        timeout: 60 //set a global ajax timeout of a minute 
       }); 
       notificationPoll(); 
      }); 
     </script> 

यह सिर्फ हो जाता है किसी कारण के लिए "निरस्त किया गया"। मैंने 'jsonp' के साथ प्रयास किया है, भले ही यह एक कोर अनुरोध नहीं है .. लेकिन यह भी काम नहीं करता है।

इस के साथ कहीं भी नहीं मिल रहा है! क्या कोई चिपका सकता है?

बहुत धन्यवाद

+0

उल्लेख करना भूल गया: जब मैं POST प्रकार के साथ $ .ajax का उपयोग करता हूं और प्रदर्शित करने के लिए कोई अधिसूचना नहीं होती है, तो कोई भी साइट पेज जिस पर jQuery कोड है, तब तक लोड नहीं होता है जब तक अधिसूचना नहीं आती है। –

+0

कंसोल लॉग त्रुटि ?? पेस्ट करें .. –

उत्तर

2

क्या getNotifications वापसी करता है तो कोई सूचना नहीं है? jQuery एक JSON प्रारूप को वापस करने की अपेक्षा करता है लेकिन जब आप केवल खाली स्ट्रिंग को प्रतिबिंबित करते हैं तो अनुरोध विफल रहता है क्योंकि प्रतिक्रिया का प्रारूप JSON नहीं है। हर बार JSON स्ट्रिंग गूंजना सुनिश्चित करें।

+0

धन्यवाद एंडी। वर्तमान में getNotifications() कोई नोटिफिकेशन नहीं होने पर शून्य वापस लौटाता है ताकि उपयोगकर्ता/अपठित नोटिफिकेशन केवल लूप हो और वास्तव में कोई नई सूचना न हो जब तक कुछ भी वापस नहीं आती। –

+0

यह किसी भी प्रतिक्रिया के साथ, बस समय समाप्ति चाहिए। शायद एक बेहतर $ .ajax संरचना व्यक्तिगत टाइमआउट, सफलता के साथ डीबग करना आसान होगा, {parse json, data_available} catch (e) {}, data_available: JSON डेटा संसाधित करें, – Waygood

+0

विफल करें ठीक है - ऐसा लगता है कि मैंने इसे संकुचित कर दिया है अंत में नीचे! जब मैं $ .ajaxSteup() को कॉल करता हूं और टाइमआउट सेट करता हूं .. यह मिलीसेकंड में टाइमआउट सेट कर रहा है? मैंने इसे 60000 (60 सेकेंड) तक बढ़ा दिया है और अब $ .get 'abort' नहीं है! हालांकि एक आखिरी समस्या - शुरुआत में एक पृष्ठ लोड करना ठीक है, हालांकि दूसरे पृष्ठ पर नेविगेट करना अभी अटक गया है। क्या पृष्ठ छोड़ने पर प्रसंस्करण प्राप्त करने का कोई तरीका है? (मुझे लगता है कि अगला पृष्ठ लोड नहीं हो रहा है ..) –

3

इसके बारे में कैसे। मुझे लगता है कि $। (Get) अधिसूचनापॉल() नामक फ़ंक्शन में है; जिसे एक बार पूरा किया जाता है।

$.ajax({ 
    url: event_feed_href, 
    async: false, 
    timeout: 60000, 
    done: function(data) { 
      var got_json=false; 
      try { 
       var json = JSON.parse(data); 
       got_json=true; 
      } 
      catch(e) { 
       // failed to return JSON data 
       alert('Wierd!'); 
      } 
      if(got_json) { 
       // process json data 
       alert('New Notification!'); 
      } 
     }, 
    always: function() { 
      notificationPoll(); 
     } 
    }); 

मैं किया उपयोग किया है और हमेशा यहाँ jQuery का कहना है के रूप में सफलता गिरावट है: असफल:

+0

लंबे मतदान मतदान क्लाइंट टाइमआउट के बिना होना चाहिए। टाइमआउट केवल नेटवर्क त्रुटियों के लिए उपयोग किया जा सकता है और कनेक्ट पुनः प्रयास करें। – Deep

3

तुम्हें यकीन समारोह एक उचित समय के भीतर समाप्त हो जाता है कि होना चाहिए। आप क्या कर सकते हैं यह है:

$ttl = 10; 
while ($ttl--) { 
    $json = Yii::app()->user->getNotifications(); 
    if (null != $json) { 
     break; 
    } 
    sleep(1); 
} 
if (null == $json) { 
    $json = json_encode(array(
     'nothing' => true 
    )); 
} 
header('Content-Type: application/json'); 
echo $json; 

Yii::app()->end(); 
return; 

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

var timer = setInterval(
    function() { 
     if (this.calling) { 
      return; 
     } 
     var fn = this; 
     fn.calling = true; 
     $.post(url) 
     .done(function(data) { 
      .. 
     }) 
     .always(function() { 
      fn.calling = false; 
     }); 
    }, 
    10000 
); 

फिर AJAX में मतदान समारोह की जांच करने की जरूरत है कॉलबैक (.done() में)) कि अधिसूचना है:

function(data) { 
    if (data.hasOwnProperty('nothing')) { 
     alert('No notifications'); 
     return; 
    } 
    console.log(data); 
    ... 
} 

अब एक महत्वपूर्ण बात यह है कि क्या की तरह अपनी अधिसूचना नज़र करता है। यहां मैंने माना है कि यह एक JSON एन्कोडेड स्ट्रिंग है। लेकिन अगर यह एक सरणी या ऑब्जेक्ट है जो Yii फ़ंक्शन इसके बदले देता है, तो आपको इसके एन्कोडिंग को संभालने की आवश्यकता होती है।यह भी क्लीनर हो सकता है, यदि कोई हो के बिना:

header('Content-Type: ... 
die(json_encode(
    array(
     'status'   => 'success', 
     'notification' => $json /* This is NULL or an array */ 
    ) 
    // Javascript side we check that data.notification is not null. 
)); 

डिकोडिंग पहले से ही jQuery द्वारा नियंत्रित किया जाता है, तो चर "डाटा" ऊपर पहले से ही एक जावास्क्रिप्ट वस्तु हो जाएगा, और आप JSON.parse फोन नहीं है। आप जांच सकते हैं कि data एक ऑब्जेक्ट है, और इसकी अपेक्षाकृत गुण हैं। यह आपको किसी भी त्रुटि के बारे में चेतावनी देगा।

, एक पृष्ठ पर नेविगेशन संभाल करने के लिए आप एक वैश्विक चर में टाइमर जब पेज onUnload() कॉल मतदान निष्क्रिय करने के लिए मतदान जावास्क्रिप्ट समारोह के setInterval() -supplied टाइमर आईडी स्टोर कर सकते हैं, और हटा सकते हैं।

1

मुझे कोड निरस्त करने में दिलचस्पी है और आपका जवाब हो सकता है। यह कई कारणों से हो सकता है

  • क्वेरी.get विफल हो रहा है। अजाक्स कॉल किसी भी कारण से काम नहीं करता है। पार्स करने में त्रुटि।
  • खराब जावास्क्रिप्ट वाक्यविन्यास। उदाहरण के लिए: सफलता हैंडलर में कोड इनपुट तर्क में घटनाओं की संपत्ति की अपेक्षा करता है जो सत्य नहीं हो सकता है।

jQuery.get के लिए, jQuery.get में सुझाव के रूप में (https://api.jquery.com/jQuery.get/) प्रलेखन, समारोह चुपचाप नाकाम रहने के कर सकते हैं, मैं .ajaxError उपयोग करने के लिए करता है, तो प्राप्त विफल हो रहा है देखने के लिए सुझाव देगा।

यदि jQuery.get() के साथ कोई अनुरोध एक त्रुटि कोड देता है, तो यह स्पष्ट रूप से विफल हो जाएगा जब तक कि स्क्रिप्ट को वैश्विक .ajaxError() विधि भी नहीं कहा जाता है। वैकल्पिक रूप से, jQuery 1.5 के रूप में, jQuery.get() द्वारा लौटाए गए jqXHR ऑब्जेक्ट की .error() विधि त्रुटि प्रबंधन के लिए भी उपलब्ध है।

जावास्क्रिप्ट वाक्यविन्यास त्रुटि के लिए, मैं फ़ायरबग डीबगर के माध्यम से कदम उठाने का सुझाव दूंगा। सफलता हैंडलर में पहली पंक्ति में ब्रेकपॉइंट जोड़ें और फिर वहां से प्रत्येक पंक्ति को चरणबद्ध करें। यह थकाऊ है, लेकिन यह काम करता है।