2013-04-18 2 views
8

मेरे पास एक PHP सर्वर फ़ाइल और एक HTML क्लाइंट फ़ाइल है, HTML फ़ाइल प्रत्येक 500 ms डेटा पुनर्प्राप्त करने के लिए सर्वर पर AJAX अनुरोध भेजती है, हालांकि यह अपेक्षा करता है कि यह क्लाइंट के डिवाइस पर स्मृति और CPU का उच्च उपयोग कर रहा है।सर्वर से क्लाइंट में डेटा भेज रहा है?

पीएचपी

if(isset($_POST['id']) && $_POST['id'] != '') 
{ 
    $id  = $_POST['id']; 
    $select = $con->prepare("SELECT * FROM data WHERE id=?"); 
    $select->bind_param('s', $id); 
    $select->execute(); 
    $result = $select->get_result(); 
    while($row = $result->fetch_assoc()) 
    { 
     echo $row['column 1'] . "\t" . $row['column 2'] . "\n"; 
    } 
} 

AJAX

function send(){ 
    var formdata = new FormData(), 
     id  = document.getElementById('id').value; 
    formdata.append('id', id); 
    var xhr = (window.XMLHttpRequest) ? new XMLHttpRequest() : new ActiveXObject('Microsoft.XMLHTTP'); 
    xhr.open('post', 'server.php', true); 
    xhr.send(formdata); 
    xhr.onreadystatechange = function(){ 
     if(xhr.readyState == 4 && xhr.status == 200){ 
      console.log(xhr.responseText); 
     } 
    } 
} 
setInterval(function(){send()}, 500); 

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

मैं PHP Socket या HttpRequest मेडथोड्स का उपयोग नहीं कर सकता क्योंकि वे मेरे होस्टिंग सर्वर पर स्थापित नहीं हैं और मुझे यकीन नहीं है कि बाद के काम क्या हैं। एकमात्र तरीका जिसे मैं सोच सकता हूं SESSIONS का उपयोग कर रहा है।

this के अनुसार PHP सर्वर सर्वर पर एक ही निर्देशिका पर सभी उपयोगकर्ता सत्रों को स्टोर करता है, इसलिए फ़ाइल पर किसी विशेष उपयोगकर्ता के लिए सत्र चर बदलना संभव हो सकता है। समस्या यह है कि उन फ़ाइलों में डेटा क्रमबद्ध है और मुझे यकीन नहीं है कि डेटा को डी-सीरियलाइज़ कैसे करें और उन्हें फिर से क्रमबद्ध करें और फिर नया डेटा सहेजें!

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

तो ऐसा करने का सबसे अच्छा तरीका क्या है? कोई भी सहायताकाफी प्रशंसनीय होगी।


अद्यतन:

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

मैंने लंबे मतदान की कोशिश की लेकिन मुझे इसके साथ कई समस्याएं थीं, flush और ob_flush() मेरे सर्वर पर काम नहीं करता है और मैं ini सेटिंग्स को नहीं बदल सकता। जब अनंत लूप की कोशिश कर रहा मैं इसे डेटा परिवर्तन पर तोड़ने के लिए नहीं मिल सकता है:

if(isset($_GET['size']) && $_GET['size'] != '') 
{ 
    $size = (int)$_GET['size']; 
    $txt = "logs/logs.txt"; 
    $newsize = (int)filesize($txt);  
    while(true) { 
     if($newsize !== $size) { 
      $data = array("size" => filesize($txt), "content" => file_get_contents($txt)); 
      echo json_encode($data); 
      break; 
     } 
     else{ 
      $newsize = (int)filesize($txt); 
      usleep(400000); 
     } 
    } 

} 

यह, पर और पर जा रहा logs.txt आकार में वृद्धि भले ही इसे तोड़ने नहीं होते रहता है! मैं आकार को बढ़ाने पर डेटा कैसे तोड़ सकता हूं और गूंज सकता हूं?

अद्यतन 2:

इसे बाहर php कैश फ़ाइल आकार बदल गया जब filesize() विधि बुला इसलिए ऊपर पाश अनिश्चित काल तक चलने होगा, उस के लिए समाधान clearstatcache() विधि है जो उपयोग करने के लिए की संग्रहित कैश भी साफ हो जाएगा है फाइल आकार लूप को फाइलसाइज परिवर्तनों को तोड़ने की इजाजत देता है।

+0

कितनी बार आप अपनी प्रतिक्रिया डेटा को बदलने की उम्मीद करते हैं देखते हैं? –

+0

यह भिन्न होता है, यह हर 10 सेकंड में या एक बार हर 10 मिनट में एक बार हो सकता है – razzak

+0

परिणाम सेट कितने बड़े हैं? केबी में? – hek2mgl

उत्तर

5

ठीक है, कई परीक्षणों और लंबे शोध के बाद मैं निष्कर्ष पर आया कि PHP सर्वर किसी निर्दिष्ट क्लाइंट के साथ कभी भी बातचीत नहीं कर सकता है जब तक कि ग्राहक पहले सर्वर से अनुरोध नहीं भेजता।

मुझे मिला एकमात्र विश्वसनीय समाधान अनंत लूप का उपयोग करना है जो केवल डेटा परिवर्तन को तोड़ देगा, इससे सर्वर पर AJAX अनुरोधों की आवृत्ति कम हो जाएगी, इसलिए प्रदर्शन में वृद्धि और मेमोरी और सीपीयू के उपयोग को कम करना ग्राहक के उपकरण, यहाँ है कि यह कैसे जाता है:

$process = $_POST['process']; 
$log = "/logs/logs.txt"; 

if($process == 'update'){ 
    //execute mysqli update command and update table. 
    $str = "Update on " . date('d/m/Y - H:i:s') . "\n";//add some text to the logs file (can be anything just to increase the logs.text size) 
    file_put_content($log, $str, FILE_APPEND);//FILE_APPEND add string to the end of the file instead or replacing it's content 
} 
else if($process == 'insert'){ 
    //execute mysqli insert command and add new data to table. 
    $str = "Added new data on" . date('d/m/Y - H:i:s') . "\n"; 
    file_put_content($log, $str, FILE_APPEND); 
} 

ऊपर कोड/अद्यतन डाटा, और सम्मिलित करता है, तो अस्तित्व में नहीं फ़ाइल log.txt पैदा करेगा:

पीएचपी 1 (डेटा अद्यतन या नए डेटा डेटाबेस के लिए सम्मिलित हैंडल्स) प्रत्येक अनुरोध पर अतिरिक्त टेक्स्ट जोड़ें। log.txt बाद में अनंत लूप "नीचे" में उपयोग किया जाएगा और जब आकार बदलता है तो लूप तोड़ देगा।

पीएचपी 2 (हैंडल डेटा अनुरोधों पढ़ने):

if(isset($_POST['id']) && $_POST['id'] != '' && isset($_POST['size']) && $_POST['size'] != '') 
{ 
    $id   = (string)$_POST['id']; 
    $init_size = (int)$_POST['count']; 
    $size  = file_exists('logs/logs.txt') ? (int)filesize('logs/logs.txt') : 0;//$size is logs.txt size or 0 if logs.txt doesn't exist(not created yet). 

    $select = $con->prepare("SELECT * FROM data WHERE id=?"); 
    $select->bind_param('s', $id); 

    while(true){ //while(true) will loop indefinitely because condition true is always met 
     if($init_size !== $size){ 
      $select->execute(); 
      $result = $select->get_result(); 
      while($row = $result->fetch_assoc()) 
      { 
       $data['rows'][] = array(
            "column 1" => $row['column 1'], 
            "column 2" => $row['column 2'], 
           ); 

      } 
      $data['size'] = $size; 
      echo json_encode($data); 
      break; //break the loop when condition ($init_size != $size) is met which indicates that database has been updated or new data has been added to it. 
     } 
     else{ 
      clearstatcache(); //clears the chached filesize of log.txt 
      $size = file_exists('logs/logs.txt') ? (int)filesize('logs/logs.txt') : 0; 
      usleep(100000) //sleep for 100 ms 
     } 
    } 
} 

AJAX:

var size = 0; //declares global variable size and set it's initial value to 0 

function send(s){ 
    var formdata = new FormData(), 
     id  = document.getElementById('id').value; 
    formdata.append('id', id); 
    formdata.append('size', s); 
    var xhr = (window.XMLHttpRequest) ? new XMLHttpRequest() : new ActiveXObject('Microsoft.XMLHTTP'); 
    xhr.open('post', 'server.php', true); 
    xhr.timeout = 25000; //set timeout on xmlhttprequest to 25 sec, some servers has short execution tiemout, in my case it's 27 sec so i set the value to 25 sec. 
    xhr.send(formdata); 
    xhr.onreadystatechange = function(){ 
     if(xhr.readyState == 4 && xhr.status == 200){ 
      var data = JSON.parse(xhr.responseText); 
      size = data.size; 
      console.log(data.rows); 
      setTimeout(function(){send(size)}, 100); //re-initiate the request after receiving data 
     } 
    } 
    xhr.ontimeout = function(){ 
     xhr.abort(); //abort the timed out xmlhttp request 
     setTimeout(function(){send(size)}, 100); 
} 
send(size); 

यह आदर्श समाधान नहीं है बल्कि यह के रूप में कम के रूप में 1 करने के लिए 2/सेकंड से मेरी XMLHTTP अनुरोधों कम/25 सेकंड, उम्मीद है कि कोई बेहतर समाधान के साथ आने में सक्षम होगा।

+4

'PHP सर्वर किसी निर्दिष्ट क्लाइंट के साथ कभी भी बातचीत नहीं कर सकता है जब तक कि ग्राहक पहले सर्वर से अनुरोध नहीं भेजता। 'इस प्रकार HTTP कैसे काम करता है https://developer.mozilla.org/en-US/docs/HTTP – Ejaz

1

सीधे सत्र संपादित करने के बारे में आपके प्रश्न के हिस्से का उत्तर दें ...

सीधे उपयोगकर्ता के सत्र में हेरफेर करने के लिए, मैं आपको बताऊंगा और किसी भी उपयोगकर्ता के सत्र आईडी (शायद साइन इन पर आपके डेटाबेस में) ट्रैक कर सकता हूं।

जब आप सर्वर पर सीधे उपयोगकर्ता के सत्र संपादित करने की जरूरत:

  1. डेटाबेस से उपयोगकर्ता की अंतिम ज्ञात सत्र प्राप्त करें।
  2. वर्तमान सत्र को बंद करने के लिए session_close() पर कॉल करें (यदि कोई है तो)।
  3. सत्र आईडी के साथ 'session_name ($ sessionId)' पर कॉल करें।
  4. उस सत्र को खोलने के लिए session_open() पर कॉल करें। $_SESSION सत्र डेटा के साथ पॉप्युलेट किया जाना चाहिए। आपको कुछ भी बेकार करने की आवश्यकता नहीं होगी।
  5. सत्र में अपने संपादन करें।
  6. डेटा को पुन: व्यवस्थित करने के लिए session_close() पर कॉल करें।

वैकल्पिक रूप से, आप सीधे सत्र फ़ाइल खोलने सकता है, unserialize() यह, डेटा को संपादित, और मैन्युअल रूप से serialize() फिर से।

+0

धन्यवाद लेकिन मुझे एहसास हुआ कि 'सत्र' काम नहीं करेगा क्योंकि यह केवल सर्वर द्वारा क्लाइंट द्वारा पढ़ा जा सकता है, इसलिए मैं सर्वर को 'xmlhttprequest' भेजना होगा और वापस वर्ग में भेजना होगा। – razzak

1

आप एक php स्क्रिप्ट के लिए AJAX अनुरोध बना सकते हैं जो कोई नया डेटा होने पर केवल डेटा लौटाएगा। जब तक कोई नया डेटा नहीं है तब तक स्क्रिप्ट एक लूप में चलती रहती है।

4

ब्राउज़र में सॉकेट का उपयोग करने की क्षमता रखने से पहले, हमने लंबे मतदान का उपयोग किया था। मूल विचार यह है कि नियमित अंतराल पर ब्राउज़र बनाने के अनुरोधों के बजाय, ब्राउज़र सर्वर से अनुरोध करेगा, लेकिन ब्राउज़र तब तक प्रतिक्रिया नहीं देगा जब तक ब्राउज़र पर साझा करने के लिए कुछ सार्थक नहीं है। इसका मतलब है कि अनुरोध 10ms या घंटों के लिए खुला छोड़ा जा सकता है।

सर्वर कुछ के साथ जवाब देने के बाद, यह एक नया AJAX अनुरोध करने के लिए ब्राउज़र का काम है। इस तरह, सर्वर के लिए हमेशा एक लाइन खुली होती है।

अधिक जानकारी के लिए this question का संदर्भ लें।

0

मुझे लगता है कि आज इस प्रश्न के लिए उत्तरदाता वेबसाइट का उपयोग करना है इसके बारे में पढ़ें। अनुरोध के बिना सर्वर नहीं है अगर कुछ सर्वर में इसे बदल आप डेटा प्राप्त कर सकते

link

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