[Tutorial zur Comet-Technik] Neue Nachrichten aus Datenbank holen

Diese Seite verwendet Cookies. Durch die Nutzung unserer Seite erklären Sie sich damit einverstanden, dass wir Cookies setzen. Weitere Informationen

  • [Tutorial zur Comet-Technik] Neue Nachrichten aus Datenbank holen

    Hallo Community!

    ich habe das Tutorial Ajax / Comet Chat Tutorial hier auf easy-coding.de gelesen: [wiki]AJAX / Comet Chat Tutorial[/wiki]

    Ich möchte nun eine Art Nachrichtensystem machen, das immer die neueste Nachricht mit der Technik aus Beispiel 2 aus der MySQL-Datenbank holt.
    Ich habe gestern dann ein paar Stunden lang rumprobiert, wo ich meinen Query dann am besten hinsetze. Jedoch bekomme ich jedes Mal einen Fehler!
    Entweder einen 500-Error von Firebug weil das PHP-Script nicht mehr funktioniert oder er gibt mir einfach keine Nachrichten aus.

    Der Query an sich stimmt. Hab auch ausprobiert hat mir die richtige Nachricht ausgegeben. Wo setze ich aber den Query in der example2-backend.php hin?

    example2-backend.php

    Quellcode

    1. <?php
    2. function getNewMessagesSince($timestamp) {
    3. if(rand(1,20) == 5) {
    4. return array(
    5. 'lastupdate' => time(),
    6. 'html' => '<p>server is still alive at '.date('Y-m-d H:i:s').'</p>'
    7. );
    8. }
    9. return false;
    10. }
    11. while(!($row = getNewMessagesSince($_POST['lastupdate']))) {
    12. // warte 0.2 Sekunden um den Server zu entlasten
    13. usleep(200000);
    14. }
    15. // liefere den Inhalt
    16. echo json_encode($row);
    Alles anzeigen


    Mein Query

    Quellcode

    1. $host = "";
    2. $user = "";
    3. $password = "";
    4. $name = "";
    5. $dbconnect = @mysql_connect($host, $user, $password) or die("Datenbank konnte nicht erreicht werden!");
    6. mysql_select_db($name, $dbconnect);
    7. mysql_query("set names utf8");
    8. $lastloaded = $_POST['lastupdate'];
    9. $messagequery = "SELECT feld1, feld2, feld3 FROM nachrichten WHERE time > $lastloaded";
    10. $newmessage = mysql_query($messagequery, $dbconnect);
    Alles anzeigen


    Meine Frage also: Wie kann ich diesen Query so einbauen, das immer die neueste Nachricht aus der Datenbank zurückgegeben und angezeigt wird?

    gcon
  • Hi,
    du musst den Code in die getNewMessagesSince werfen.
    Ich habe es dir mal vorbereitet:

    Quellcode

    1. function getNewMessagesSince($timestamp) {
    2. $lastupdate = array();
    3. $html = '';
    4. $sql = 'SELECT feld1, feld2, feld3, time FROM nachrichten WHERE time > '.intval($timestamp);
    5. $res = mysql_query($sql);
    6. while ($row = mysql_fetch_array($res)) {
    7. $lastupdate = $row['time'];
    8. $html .= '<li>'.$row['feld1'].'</li>';
    9. }
    10. if(count($lastupdate)) {
    11. rsort($lastupdate);
    12. return array(
    13. 'lastupdate' => array_shift($lastupdate),
    14. 'html' => $html
    15. );
    16. }
    17. return false;
    18. }
    Alles anzeigen
  • Quellcode

    1. <?php
    2. function getNewMessagesSince($timestamp) {
    3. $lastupdate = array();
    4. $html = '';
    5. $sql = 'SELECT feld1, time, feld3 FROM nachrichten WHERE time > '.intval($timestamp);
    6. $res = mysql_query($sql);
    7. while ($row = mysql_fetch_array($res)) {
    8. $lastupdate = $row['time'];
    9. $html .= '<li>'.$row['feld3'].'</li>';
    10. }
    11. if(count($lastupdate)) {
    12. rsort($lastupdate);
    13. return array(
    14. 'lastupdate' => array_shift($lastupdate),
    15. 'html' => $html
    16. );
    17. }
    18. return false;
    19. }
    20. while(!($row = getNewMessagesSince($_GET['lastupdate']))) {
    21. usleep(200000);
    22. }
    23. echo json_encode($row);
    24. ?>
    Alles anzeigen


    So sieht das jetzt aus. Zusammengebastelt. Funktionieren tut es immer noch nicht.
    Ich trage eine Nachricht via Ajax in die Datenbank ein, das PHP-Script lädt jedoch trotzdem immer weiter und weiter...

    Wo wird eigentlich die Variable $timestamp festgelegt? Muss ich die nicht erst definieren?

    LG gcon

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von gcon ()

  • $timestamp ist nirgends definiert. Und wenn ich es definiere mit $timestamp = $_POST['lastupdate']; lädt das PHP-Script trotzdem weiter.

    Der Ajax-Request wird ja gestartet sobald die Seite geladen ist. Mit diesem Request wird das PHP-Script aufgerufen und der lastupdate-Wert übergeben.
    Diesen Wert brauche ich ja dann in meinem Query. Der Wert wird anscheinend auch in den Query übergeben: Wenn ich die Seite direkt mit ?lastupdate=1301840343 aufrufe, steht das ganze auch in dem Query drinnen(echo $sql;). Ich weiß nicht an warum mir das Script nichts zurückgibt...
  • $timestamp ist definiert.
    Aufruf: getNewMessagesSince($_GET['lastupdate'])
    Nutzung: function getNewMessagesSince($timestamp)

    Das PHP Script lädt so lange weiter, bis er irgendwelche Ergebnisse findet. Ignoriere doch erstmal den COMET Teil und schau ob dein SQL korrekt ist.
    Statt der while Schleife machst du einfach ein print_r

    Quellcode

    1. print_r(getNewMessagesSince($_GET['lastupdate']));
  • Entschuldigung, dass ich mich erst so spät wieder melde, aber wir hatten diese Woche Englisch-Speaking AP.

    Ich habe noch nie wirklich mit Funktionen gearbeitet. Vielleicht ist das auch mein "Manko". Jedenfalls blicke ich nicht ganz durch das System dieses Skripts. Werde mich wohl mal mit Funktionen beschäftigen müssen.

    Der $timestamp-Wert wird in den Query übertragen.

    Quellcode

    1. <?php
    2. function getNewMessagesSince($timestamp) {
    3. $lastupdate = array();
    4. $html = '';
    5. mysql_select_db($Name, $connect);
    6. mysql_query("set names utf8");
    7. $sql = 'SELECT id, time, nachricht FROM nachrichten WHERE time > '.$timestamp;
    8. $res = mysql_query($sql);
    9. while ($row = mysql_fetch_array($res)) {
    10. $lastupdate = $row['time'];
    11. $html .= '<li>'.$row['nachricht'].'</li>';
    12. }
    13. if(count($lastupdate)) {
    14. rsort($lastupdate);
    15. return array(
    16. 'lastupdate' => array_shift($lastupdate),
    17. 'html' => $sql
    18. );
    19. }
    20. return false;
    21. }
    22. print_r(getNewMessagesSince($_GET['lastupdate']));
    23. ?>
    Alles anzeigen


    Und der Query ist korrekt:

    Quellcode

    1. Array
    2. (
    3. [lastupdate] =>
    4. [code=html] => SELECT id, time, nachricht FROM nachrichten WHERE time > 1301839190
    5. )
  • So okay, hab ich gemacht. Ich bekomme jetzt ein Ergebnis wenn ich die Datei direkt mit ?lastupdate=.. aufrufe. Also er gibt mir alle Einträge seit diesem Zeitpunkt aus. Im Chat selbst verändert sich jedoch immer noch nichts..

    Hier mal wieder die aktuelle Version:

    Quellcode

    1. <?php
    2. function getNewMessagesSince($timestamp) {
    3. $lastupdate = array();
    4. $html = '';
    5. $sql = 'SELECT id, time, nachricht FROM nachrichten WHERE time > '.$timestamp;
    6. $res = mysql_query($sql);
    7. while ($row = mysql_fetch_array($res)) {
    8. $lastupdate[] = $row['time'];
    9. $html .= '<li>'.$row['nachricht'].'</li>';
    10. }
    11. if(count($lastupdate)) {
    12. rsort($lastupdate);
    13. return array(
    14. 'lastupdate' => array_shift($lastupdate),
    15. 'html' => $html
    16. );
    17. }
    18. return false;
    19. }
    20. while(!($row = getNewMessagesSince($_GET['lastupdate']))) {
    21. usleep(200000);
    22. }
    23. echo json_encode($row);
    24. ?>
    Alles anzeigen
  • Quellcode

    1. $Host = "";
    2. $User = "";
    3. $Pw = "";
    4. $Name = "";
    5. $connect = @mysql_connect($Host, $User, $Pw) or die("Fehler!");
    6. mysql_select_db($Name, $connect);
    7. mysql_query("set names utf8");


    Du meinst den DB-Connect? Den hab ich schon drin, habe ihn bloß hier im Forum aus dem Script geworfen.

    Ich habe den Fehler jetzt gefunden. Das Javascript übergibt den Timestamp anscheinend nicht richtig an die Datei. Bei direkten Aufrufen mit ?lastupdate.. funktioniert alles.

    Habe jetzt mal einen Ajax-Request mit jQuery gemacht und siehe da, es funktioniert!
    Aber wie starte ich mit jQuery einen erneuten Request, sobald der neue vorüber ist?

    Quellcode

    1. var lastupdate = Math.round((new Date()).getTime() / 1000);
    2. $.ajax({
    3. type:'POST',
    4. url:'/nachrichten.php',
    5. data:'lastupdate='+lastupdate,
    6. contentType: "application/x-www-form-urlencoded;charset=ISO-8859-15",
    7. success:function(response){
    8. $("#nachrichten").append(response);
    9. }
    10. });


    Also was müsste ich noch hinzufügen, dass das Script in jQuery genauso läuft?

    LG gcon
  • Habe gerade noch einen Fehler entdeckt. Anscheinend stimmt der Timestamp von jQuery und der Unix-Timestamp nicht ganz überein. Denn wenn ich die Seite reloade, zeigt er mir in etwa 5-10 Sekunden immer wieder den gleichen Eintrag an.
    Wie könnte ich den Fehler noch beheben?

    Ja, aber das Problem ist, dass das Javascript aus dem Tutorial nicht funktioniert, da der Timestamp(?lastupdate=..) nicht übergeben wird.
    Deshalb habe ich den Javascript-Code jetzt rausgenommen und mit dem jQuery-Code von meinem Beitrag vorher ersetzt. Jetzt funktioniert es.
    Jedoch wird noch kein neuer Request gestartet, nachdem der andere zurückgegeben wurde.

    Mein ganzer Code ist schon online. Die jQuery-Datei und die nachrichten.php. Der Rest von den Seiten hat eigentlich nichts mit dem Nachrichtensystem zu tun.
  • Sag mal, wann genau hast du in deinem Code eigentlich von $_POST zu $_GET gewechselt. Du verwendest die falsche Variable, kein Wunder, dass es nicht funktioniert.
    Im Download des Wiki Artikels wirst du unter example3 ein neues Beispiel mit MySQL finden. Dort werden auch neue Nachrichten eingetragen. Einen neuen Wiki Beitrag mit Erläuterungen stelle ich bald online.

    UPDATE:
    Den Wiki Artikel findet ihr nun online unter [wiki]Comet Chat Beispiel mit PHP + MySQL[/wiki]
  • Das mit der $_GET-Variable habe ich schon wieder geändert.

    Habe es mittlerweile mit jQuery geschafft.
    Das Nachrichtensystem funktioniert jetzt.

    Jedoch gehen Nachrichten verloren, wenn man zu schnell hintereinander eingibt. Das heißt der laufende Request gibt mir einen Teil der Nachrichten nicht aus.
    Weißt Du wie ich den "Bug" noch wegbringen kann, sodass alle Nachrichten ausgegeben werden, auch wenn man sie in einer noch so kurzen Zeitspanne abschickt?
    Ich will eigentlich keinen Timeout verwenden, da das den Chat doch enorm einschränken würde.

    LG gcon