Avatar billede DGudiksen Nybegynder
25. december 2012 - 16:38 Der er 10 kommentarer

Long polling med Ajax & php

Hej eksperter, er igang med at lege med lidt Long polling i PHP samt ajax.

Jeg har fået lavet mig et script som ser således ud:

Index.html:

<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title> Comet :  Ajax </title>
<style>
    body { margin:0px; padding:0px; overflow:hidden; }
    #msg { margin:0px; padding:10px;width : 700px; height:300px; overflow-y:scroll; border:1px solid #000; }
    #send{ width: 700px; height:20px; overflow-y:scroll; }
    #brugernavn{ width: 200px; height:20px; overflow-y:scroll; }
</style>

<script src="jquery.js"></script>
<script>

var timestamp = null;
function comet() {
alert("test2");
    $.ajax({
        type : 'Get',
        url  : 'read.php?timestamp=' + timestamp,
        async : true,
        cache : false,
       
        success : function(data) {
                    var json = eval('(' + data + ')');
                    if(json['msg'] == ''){
                        $('#msg').html('No msg');                       
                    }else {
                        $('#msg').html(json['msg']);
                        $('#msg').animate({scrollTop: $('#msg').get(0).scrollHeight},200);
                    }
                    timestamp  = json['timestamp'];
                    setTimeout('comet()', 1000);
                   
        },
        complete: function(){
  alert("test");
}
    });
}

$(function() {
    comet();
    $('#send').bind('keyup', function(e) {
        var msg = $(this).val();
        var name = $('#brugernavn').val();
        if(e.keyCode == 13 && e.shiftKey) {
                    return;
        }else if(msg!='' && e.keyCode == 13 && document.getElementById('brugernavn').value != 0) {
            $.ajax({
                type : 'GET',
                url  : 'write.php?msg='+ msg +'&name='+ name,
                async : true,
                cache : false
            });
            $(this).val('')
        }
    })
});
</script>
</head>
<body>
<div id="msg"> </div>
<br />
Brugernavn: <input type="text" id="brugernavn" value=""><br>
Besked: <input type="text" id="send" name="msg" value="" width="200px">
</body>
</html>


read.php:

<?php
    $filename = 'data.txt';
    $last = isset($_GET['timestamp']) ? $_GET['timestamp'] : 0;
    $current = filemtime($filename);
    while( $current <= $last) {
        usleep(10000);
        clearstatcache();
        $current = filemtime($filename);
    }
   
    $response = array();
    $response['msg'] = file_get_contents($filename);
    $response['timestamp'] = $current;
    echo json_encode($response);   
?>


Mit problem er at hvis der ikke er kommet noget i tekst filen, så timer PHP ud efter 30 sekunder. Men sender ikke noget "comeback" til ajax delen, hvilket gør at hvis der ikke er sket noget nyt i 30 sekunder, bliver den ikke "opdateret" ude i client, og man er nødtil at refresh siden.

Nogle som har en ide til hvordan det kan laves?
Avatar billede olebole Juniormester
25. december 2012 - 17:06 #1
<ole>

Det forstår jeg ikke noget af. Der er ikke noget, der timer ud. Dit script forespørger serveren hvert sekund (hvilket i øvrigt er i overkanten) - og hver forespørgsel er kun et lillebitte 'ping', der varer et par millisekunder.

Hvad sker der - og hvad havde du forventet ville ske?

/mvh
</bole>
Avatar billede DGudiksen Nybegynder
25. december 2012 - 17:10 #2
Ole, den forespørger kun hvis den får data tilbage fra read.php - Så forespørger den igen et sekund efter. KUN hvis den får data tilbage.

Og hvis ikke read.php giver den noget tilbage, f.eks hvis der ikke er blevet tilføjet noget nyt i data.txt. Så timer den bare ud. Altså ikke forespørger igen, hvilket jeg gerne vil have den til. Uden altså at den forespørger hvert sekund.

Forstår du det? :)
Avatar billede DGudiksen Nybegynder
25. december 2012 - 17:13 #3
Så skal den kun forespørge når de 30 sekunder er gået (30 sekunder er der hvor PHP scriptet udløber fordi whilen ikke bliver afsluttet)
Avatar billede olebole Juniormester
25. december 2012 - 17:50 #4
Det skyldes vel, at du kun starter din setTimeout, hvis der er success  =)

I det hele taget kan jeg ikke få din kode til at give mening. Hvad laver din sleep i PHP-koden?
Avatar billede DGudiksen Nybegynder
25. december 2012 - 17:54 #5
ole. Det er et stump kode jeg har fundet på nettet, og jeg prøver at arbejde med det. Så indtil jeg har fået det til at virke, har jeg ikke turde at slette noget i koden indtil videre.

Ja jeg ved godt jeg kun har timeout i succes, men det kommer aldrig til complete: har også prøvet med error: men ingen af dem bliver "kaldt" hvad kan det skyldes?
Avatar billede arne_v Ekspert
25. december 2012 - 18:19 #6
sleep simulerer vel en request som er lang tid om at svare og kan derfor bruges til demo formaal

men har naeppe nogen mening i rigtig kode
Avatar billede olebole Juniormester
25. december 2012 - 18:21 #7
Det er muligt, men for mig giver den ikke mening. Derudover er det en skodkode, da den bruger eval til at omdanne json-strengen til et objekt. Det er en absolut no-go! I stedet bør man bruge JSON.parse. eval brugte man i begyndelsen, da Ajax blev født, men det viste sig hurtigt at være en foræring til brugere med ubehagelige hensigter.

Umiddelbart ville jeg smide den pågældende kode ud og finde noget nyere fra en pålidelig kilde  =)
Avatar billede olebole Juniormester
25. december 2012 - 18:22 #8
- og #7 var en kommentar til #5  *o)
Avatar billede DGudiksen Nybegynder
25. december 2012 - 18:34 #9
olebole - Jeg har kigget internettet tyndt efter et lign script. men kan ikke finde noget.
Avatar billede olebole Juniormester
25. december 2012 - 18:46 #10
Jeg har ikke nogen idé om, hvad du vil lave, eller hvordan det præcist skal fungere, så det er svært at anvise noget bedre
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester