Long Polling ile Sayfa İçeriği Güncelleme

 bcakir
 31 Temmuz 2011

Merhaba arkadaşlar ben uzun zamandır facebook‘un haberler bölümünü nasıl çok fazla trafik sorunu yaşamadan yeni ileti gelince otomatik olarak güncellediğini araştırıyordum. Klasik yöntemler kullanıldığında; kullanıcı sayısı fazla olunca sistem kilitleniyordu. Yaptığım bütün araştırmalar sonuncunda bir önceki makalemde de yazmış olduğum Tornado’yu kullandıklarını öğrendim. Eğer Tornado hakkında bilgi edinmek istiyorsanız önceki makalemi okumadan geçmeyin. Bu makalede ise Tornado’nun çalışma mantığı olan Long Poling yöntemini öğrenmek için temel düzeyde bir Php uygulaması geliştireceğiz. Şimdi Polling olayını açıklayarak makalemize başlayalım.

Ajax ile Php’den veri isteme olayına Polling deniliyor. Long Polling ise istenilen verinin daha uzun süre aralıklarla ve çok fazla trafik yaratmadan istenme olayıdır. Fakat aklınıza bir soru takılmış olabilir. Eğer uzun aralıklarla veri almak istiyorsak sayfa içeriğini geç güncellemiş olmaz mıyız diye. İşin tam da püf noktası burası. Facebook, Twitter ve FriendFeed’in de kullandığı yöntem basitçe şu şekilde. Ajax ile Php betiğine son aldıkları veriyi gönderiyorlar. Php betiğinde ise Ajax’tan alınan veri sonsuz bir döngü içerisinde. Bu alınan değer, veritabanına kaydedilen en son veri olarak kaldığı sürece bu döngü bitmiyor ve geriye sonuç döndürülmüyor. Ama alınan bu veriden sonra başka yeni bir veri girildiyse döngü kırılıp geriye sonuç döndürülüyor, yeni girilen veriler sayfaya ekleniyor ve yapılan bütün işlem tekrar baştan başlıyor.

<html>
<head>
<title>Long Polling</title>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script>
<script type="text/javascript">
$(document).ready(function() {
    Gonderme("son verimin id değeri...");
});

function Tekrar() {
    gelen=document.getElementById("sonuc").innerHTML
    document.getElementById("sonuc").innerHTML="";
    Gonderme(gelen);
}

function Gonderme(verim) {
    $.ajax({
        type:'POST',
        url:"veri.php?veri="+verim,
        success: function (msg) {
            $('div#sonuc').html(msg);
        }
    });
    setTimeout("Tekrar()",2000);
}
</script>
</head>
<body>
<div id="sonuc"></div>
<div id="eskiler">Bekleyin...</div>
</body>
</html>

Yukarıda iki tane fonksiyon oluşturduk. Bu fonksiyonları birbiri içerisinden çağırarak sürekli bu işlemi tekrarlamalarını sağladık. Yani bir kere veri geri gelince işlem bitmeyecek, sayfa açık olduğu sürece işlem tekrarlanacak. Sayfa ilk açılınca Gonderme fonksiyonunu çalıştırdık ve son verimizi gönderdik. Geriye veri gelince ise sonuc adlı div’e yazdırdık. Fonksiyonun sonunda 2 saniye bekletme işlemini verinin geldiğini görmeniz için yaptım. Yoksa hızlıca Tekrar fonksiyonunu işletiyor. Burada bulunan sonuc adlı div’in içeriğini sil kodundan dolayı gelen veriyi göremiyorduk. Basitçe mantığımız bu şekilde. Şimdi de veri.php betiğine geçelim.

<?php
//veri.php olarak kaydedin
if (isset($_GET['veri'])){
    $gelen=$_GET['veri'];

    $sayac = 1;
    while ($sayac <= 10) {
            $sayi=Rand(1,4);
            if($sayi==4){
                $sayac=11;
                echo "Yeni veri geldi...";
            }
            sleep(2);
    }
}
?>

İlk önce gelen verimizi alıyoruz. Ben burada onunla herhangi bir işlem yapmadım ama siz onunla veritabanında bulunan son kayıtın aynı olup olmadığını kontrol etmeniz gerekiyor. Daha sonra while döngüsü kurdum ve bu işlemi 10’dan büyük oluncaya kadar sürdürdüm. Yani sonsuz bir döngü kurdum. Bu döngü sadece $sayac 10’dan büyük olursa durur. Daha sonra rastgele sayı türettirdim ve rastgele türetilen sayı 4 olunca da $sayacı 10’dan büyük bir rakam olan 11 yaptım ve yeni veri geldi diye geriye sonuç döndürdüm. Siz buraya veritabanı kodlarınızı koyup, gelen veri id’si ile veritabanında bulunan son kayıt id’sinin aynı olup olmadığını kontrol etmeniz lazım. En sonda ise sleep koduyla bu işlemin ne kadar sıklıkla (2 saniye yaptım) yapacağını belirttim. Temel olarak uygulamamız bu şekilde. Long Polling yönteminin en büyük avantajı diğer yöntemlerdeki gibi sürekli Ajax betiğimiz ile veri alış-verişinde bulunmayıp sadece yeni veri gelince veri transferi yapıyor olmasıdır. Şunu belirtiyim ki; bu yöntem serverınıza ekstra yük bindirecektir fakat diğer yöntemlerle karşılaştırıldığında çok daha az miktarda.

 2.165 Okunma

Bu yazıya 13 yorum yapılmış.

  1. Açıklayıcı bir yazı olmus.Aklıma takılan 2 soru mevcut.
    -Veritabanından veriyi aldım sorun yok fakat yeni veri eklendikce değil hep güncelliyor o bölümü. Neden ?
    -Birde sonuc divi kaybolup geliyor bunu nasıl engelleriz ?

    • success: function (msg) {$(‘div#sonuc’).html(msg);}
      kısmını uygulamana göre düzenlemen gerekiyor; yani, yeni veri gelince çalıştır, gelmeyince çalıştırma gibi. if else kontrol yapısı yazarsan sorularına çözüm bulursun.

      • hocam üstünde çok düşündüm ne yaptıysam olmadı yeni veri gelip gelmediğini o kısımda nasıl anlıycaz çözemedim…

  2. ilk programı çalıştırdığında veritabanındaki son kayıt id değerini alman gerekiyor. sonra da ajax isteği yapıp bu kayıt id değerinin veritabandaki son id değerinden küçük olup olmadığını kontrol edeceksin. eğer küçükse yeni veri gelmiştir, değilse gelmemiştir.

    • sormak istediğim aslında mantığı değil mantığını anladım fakat javascript bilgim olmadığı için yapamıyorum.Örnek bi kaç kod yazabilirmisiniz rica etsem.

      • Şuan için maalesef zamanım yok, ödevler ve birkaç işimden dolayı. Müsait olunca yazarım.

  3. eywallah hocam güzel bir makale ve tornado dedikleri şeyin sonunda ne olduğunu öğrendim teşekkür ederim

  4. Hocam Paylaşım için çok sağolun eliniz dert görmesin pek ajax bilgim yok o yüzden bir sorum olucak benim facebook tarzı bir duvarım var ben şuanda sizin daha önce verdiğiniz reflesh kodunu eklediğimde sayfa bi süre sonra checking connection yazıp duvardan verileri çektiğim data.php sayfasına atıyor :S Birde mesala reflesh ettiğimiz div sayfanın orta bölümünde olsun diyelim biz sayfanın en altındayız reflesh işlemi olduğunda o divin üzerine gidiyor sayfa :D:D neden olabilir acaba?

    • Sayfanda büyüme küçülme işlemi olursa sayfanın odak yeri kayar. Eğer büyüme küçültme işlemini ortadan kaldırırsan, sayfanda kayma olmayacaktır.

  5. Uzun zamandır düşündüğüm bi türlü tam olarak nasıl yapıldığına kanaat getiremediğim bi konuydu:) çok faydalı bi yazı oldumuş. En azından kendi adıma bunu diyebilirim teşekkür ettim emeği geçen herkese..

  6. Cevabınız için çok teşekkür ederim ama ne gibi bir büyütme küçültme anlıyamadım 🙁 sorun hala devam ediyor :S

    • Sayfanda yazı var örneğin. Yenisi yüklenirken başka bir şey gösterirsen melasa “yükleniyor bekleyin…” bu sayfada küçülüp büyümeye neden olacağı için, sayfan kayacaktır.

  7. Şöle bi cevap vereyim soruma benim çektiğim php dosyasının içinde meta tagları html başlıkları filan vardı çünkü o sayfada çektiğim verileri ajax ile de beğendirmem gerekiyordu ve o kodlar o sayfada olunca çalışıyordu bende beğendirmenin başka bir yöntemini aramaya başlayıp o sayfadan html css vs. kodlarını silince durum düzeldi merak eden arkadaşlar olur belki diye belirtmek istedim teşekkür ederim sağolun 🙂

Yazı hakkında görüşlerinizi belirtmek istermisiniz?

Daha fazla Ajax, JQuery, Php
Kapat