Long Polling Uygulaması

 bcakir
 5 Kasım 2011

Merhaba arkadaşlar bu yazımda; daha önceki makalemde temellerini anlattığım long polling tekniğiyle, veritabanından kayıt alıp, kayıt girilme işlemlerini de içerecek çok daha kapsamlı bir örnek yazacağım. Fakat gerçek long polling uygulamaları için ona uygun server gerekiyor çünkü normal sunucular 30 saniye gibi bir sürede veri akışını sonlandırmak istiyor. Bundan dolayı da sunucu bağlantı problemi oluyor. Gerçek long polling uygulamalarında (python ile yazılıyor) yeni verinin gelip gelmediği sunucu tarafında kontrol ediliyor ve sadece yeni veri geldiğinde, sonuç kullanıcı (client) tarafına gönderiliyor. Ama bu tür uygulama az önce de belirttiğim gibi serverın zaman aşımı hatası vermesine neden oluyor. Bundan dolayı da, biz bu kontrolü kullanıcı (client) tarafına alarak uygulama yapacağız. Kısacası, tam manasıyla gerçek bir long polling uygulaması yazamayacağız ama yine de klasik yöntemlere göre çok daha performanslı çalışacak. Bu uygulamamız baya uzun olacak bu yüzden de uygulamanın önemli noktalarına değineceğim. Ama merak etmeyin uygulamanın veritabanını da içeren bütün içeriği yazının sonunda bulabileceksiniz. Ayrıca bir konuya daha değinmek istiyorum. Bu tekniği sadece sayfa güncelleme için değil sohbet (chat) tarzı uygulamalarda yazılan son yazıları güncellemek için de kullanabilirsiniz. Şimdi uygulamamızın index.html sayfasını yapalım.

<!DOCTYPE html>
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=iso-8859-9" />
<title>Long Polling Tekniği | bcakir</title>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.6.4/jquery.min.js"></script>
<script type="text/javascript">
var son_id;
$(document).ready(function() {
    idAlma();
    eskiler();
});

function idAlma(){
    $.ajax({
        type:'POST',
        url:"sayac_id.php",
        success: function (msg) {
            son_id=parseInt(msg);
        }
    });
    setTimeout("gonderme()",10000);
}

function eskiler(){
     $.ajax({
        type:'POST',
        url:"kayit_al.php",
        data:"veri=eskiler",
        success: function (msg) {
            $('#eskiler').html(msg);
        }
    });
}

function tekrar(){
    gonderme(son_id);
}

function gonderme(){
    $.ajax({
        type:'POST',
        url:"sayac_id.php",
        success: function (msg) {
            if(parseInt(msg)>son_id){
                kayitAl(son_id);
                son_id=parseInt(msg);
            }else{
                setTimeout("tekrar()",10000);
            }
        }
    });
}

function kayitAl(verim){
    $.ajax({
        type:'POST',
        url:"kayit_al.php",
        data:"veri="+verim,
        success: function (msg) {
            oncekiler=$('#sonuc').html();
            $('#sonuc').html(msg+oncekiler);
        }
    });
    setTimeout("tekrar()",10000);
}

function kayitYap(){
    verim=$('#icerik').val();
    $.ajax({
        type:'POST',
        url:"kayit_yap.php",
        data:"veri="+verim,
        success: function (msg) {
            $('#icerik').val('');
        }
    });
}
</script>
</head>
<body>
<div id="sonuc"></div>
<div id="eskiler"></div>
<div style="margin-top: 10px;">
Yeni İçerik Ekle:
<input type="text" id="icerik" />
<input type="button" value="Gönder" onclick="kayitYap()"/>
</div>
</body>
</html>

Uygulamamızın temelini oluşturan mantığı yukarıda yaptık. İçerik güncelleme süresini 10 saniye düşündüm. Bu zamanı siz değiştirebilirsiniz ama bana göre uygun bir süre, bir kişinin yazılanı görüp cevap vermesi için. Uygulamamızda hem veritabanı hem de dosya işlemlerini birlikte kullanacağız. Şimdi de sırasıyla bunları yapmaya başlayalım.

<?php
//sayac_id.php olarak kaydedin
//son kayıt değerinin alınması
$oku = @fopen('sayac.txt', 'r');
$rakam = @fread($oku, filesize('sayac.txt'));
@fclose($oku);

//sayının gönderilmesi
echo $rakam;
?>

Uygulamamız son kayıt id değerine göre güncelleme yapacak bundan dolayı da bunu sayac.txt dosyasına her kayıt girilme sonrası artırarak yazdırıyoruz ve bu dosyadan hem veritabanına bağlanmak hem de sunucuya ağır yük bindirmek zorunda kalmadan son kayıt değerini alabiliyoruz.

<?php
//kayit_al.php olarak kaydedin
include "baglanti.php";

// Türkçe karakter seti seçimi
header("Content-Type: text/html; charset=iso-8859-9");

if ($_POST['veri']=='eskiler'){
    // Long_polling Tablosundan Kayıt Al
    $sec = mysql_query("Select id, icerik From long_pooling Order By id Desc");
    while ($goster = mysql_fetch_array($sec)){
        echo $goster['id']. ' - '.$goster['icerik']."<br />";
    }
}else{
    $gelen=$_POST['veri'];
    // Long_polling Tablosundan Kayıt Al
    $sec = mysql_query("Select id, icerik From long_pooling Where id>'{$gelen}' Order By id Desc");
    while ($goster = mysql_fetch_array($sec)){
        echo $goster['id']. ' - '.$goster['icerik']."<br />";
    }
}

//veritabanı bağlantısı kapatma
mysql_close();
?>

Yukarıda veritabanından kayıt alma işlemlerini yaptık. Bu kodları hem eski girilen verileri hem de sonradan eklenen verileri almada kullanıyoruz. Ayrı ayrı iki tane veri alma betiğini yazmamıza gerek yok. Son olarak veri kaydetme işlemini ve gerekli olan açıklamaları da yaparak yazıma son vereyim.

<?php
//kayit_yap.php olarak kaydedin
include "baglanti.php";

// Türkçe karakter seti ayrlaması
$gelen=iconv("UTF-8", "ISO-8859-9", $_POST['veri']);

// Long_polling Tablosuna Kayıt Yap
$query = "INSERT INTO long_pooling (icerik) VALUES ('{$gelen}')";
mysql_query("SET NAMES 'latin5'");
mysql_query("SET CHARACTER SET latin5");
mysql_query("SET COLLATION_CONNECTION = 'latin5_turkish_ci'");
$result = mysql_query($query, $baglan);
if(!$result){echo "Kayıt hatası";}

//son kayıt değerinin alınması
$oku = @fopen('sayac.txt', 'r');
$rakam = @fread($oku, filesize('sayac.txt'));
@fclose($oku);

//sayac.txt sayfasının oluşturulması
$yaz = fopen('sayac.txt', 'w');
$goruntulenme = $rakam+1;
//son kayıt değerinin 1 artırılması
fwrite($yaz, $goruntulenme);
fclose($yaz);

//veritabanı bağlantısı kapatma
mysql_close();
?>

Yukarıda ise girilen içeriği kaydetme ve sayac.txt dosyasında bulunan son kayıt değerini artırma işlemini yaptık. Böylece uygulamamızın sonuna doğru gelmiş olduk. Eğer tam long polling uygulaması elde etmek isteseydik, gonderme fonksiyonu içerisinde yaptığımız son kayıt id değeri kontrolünü, kayıt_al.php içerisine yapmamız ve bu kontrolü, yeni kayıt gelene kadar sleep(10); fonksiyonuyla tekrar ettirmemiz yeterliydi. Fakat süre aşımı problemimiz bunu yapmamıza engel oluyor. Uygulamanın bütün betiği ve dosyalarının olduğu çalışır halini buradan indirebilirsiniz. Uygulamamızı geliştirip, gerekli açıklamalarını da yaparak bir yazının daha sonuna gelmiş olduk. Yararlı olması dileğiyle.

 2.221 Okunma

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

  1. Çok teşekkür ederim heryerde bunu aradım 😀 En güzel anlatım senindi 😀

  2. tek kelime mükemmel..

  3. Emeğine sağlık hocam.

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

Daha fazla Ajax, JQuery, MySQL, Php
Kapat