Lighttpd'nin v1.4.22 birden çok örneğini sorun Ajax uzun yoklama (kuyruklu yıldız) + php

3 Cevap php

Ben bu siteye yeni am, bu yüzden gerçekten benim soru ile ilgili tüm gerekli bilgileri sağlamak umuyoruz.

Ben uzun yoklama kullanarak bir "yeni bir mesaj geldi bildirim" oluşturmak için çalışıyorum. Şu anda benim sitedeki her sayfanın window.onLoad olayı tarafından Yoklama isteğini başlatan duyuyorum.

Sunucu tarafında ben sonsuz bir döngü var:

while(1){
 if(NewMessageArrived($current_user))break;
 sleep(10);
}
echo $newMessageCount;

İstemci tarafında ben aşağıdaki (basitleştirilmiş) ajax fonksiyonları vardır:

poll_new_messages(){
 xmlhttp=GetXmlHttpObject();
 //...
 xmlhttp.onreadystatechange=got_new_message_count;
 //...
 xmlhttp.send();
}

got_new_message_count(){
 if (xmlhttp.readyState==4){
  updateMessageCount(xmlhttp.responseText);
  //...
  poll_new_messages();
 }
}

Sorun her sayfa yük ile, yukarıdaki döngü tekrar başlar olmasıdır. Sonuç sonunda benim sunucu askıda hale birden sonsuz döngüler for each user olduğunu.

* NewMessageArived() function yeni okunmamış mesajlar için MySQL DB sorgular.

* Php script başında ben $current_user değerini elde etmek için start_session() çalıştırın.

Bana bu döngü içindeki time() bir dosyaya yazarak bu davranışı hata ayıklamak için kolay yüzden ben şu anda bu sitenin tek kullanıcısıyım. Ne görmek dosya daha sık kez 10 saniyeden daha yazılmakta olduğunu, ama sayfa sayfa giderken sadece başlar.

Herhangi bir ek bilgi yardımcı olabilecek varsa bana bildirin lütfen.

Teşekkür ederim.

3 Cevap

Benim sorun için bir çözüm buldum. Bu COMET kullanılan ve nasıl ölçeklenebilir bu çözüm ediliyor tekniktir ise herkes, söyleyebilir sevinirim.

Ben böyle bir kullanıcı bazlı semafor kullandı:

$sem_id = sem_get($current_user);
sem_acquire($sem_id);
while(1){
 if(NewMessageArrived($current_user))break;
 sleep(10);
}
sem_release($sem_id);
echo $newMessageCount;

Uzun yoklama, açılış 30 saniye sonra zaman aşımı için ortak görünüyor. Yani süre döngü 30 saniye sonra 'KAPAT' echo olabilir.

while(!$new_message && $timer < 30){
    $new_message = NewMessageArrived($current_user);
    if(!$new_message) {
    	sleep(10);
    	$timer += 10;
    }
}
if($newMessageCount) {
    echo $newMessageCount;
} else {
    echo 'CLOSE';
}


Javascript, sen KAPAT için dinleyebilirsiniz.

function poll_new_messages(){
    xmlhttp=GetXmlHttpObject();
    //...
    xmlhttp.onreadystatechange=got_new_message_count;
    //...
    xmlhttp.send();
}

function got_new_message_count(){
    if (xmlhttp.readyState==4){
    	if(xmlhttp.responseText != 'CLOSE') {
    		updateMessageCount(xmlhttp.responseText);
    	}
    	//...
    	poll_new_messages();
    }
}

Şimdi, PHP ne olursa olsun, 30 saniye içinde bir yanıt döndürür. Eğer sayfada kalır kullanmak, ve bir KAPAT alırsanız, sadece sayfada sayısını güncelleme yok, ve yeniden isteyin.

Kullanıcı için yeni bir sayfa taşırsa, PHP örneği 30 saniye içinde ne olursa olsun Döngüyü durdurmak ve bir yanıt döndürür. Olsa yeni bir sayfada olmak, bu bağlantı umursamaz XHR artık yok, bu yüzden another döngü başlatmak değil.

Sen connection_aborted() periodically. Note that connection_aborted() bağlantısı bazı çıktı yazılı ve yaptık kadar aslında iptal edildi olduğu gerçeği üzerinde almayabilir kontrol deneyebilirsiniz bir flush() .

Php bağlantı kendisine yakın haber ve otomatik olarak komut öldürmek için Aslında, sadece periyodik olarak bazı çıktı üreten yeterli olabilir.