Es ist einfacher als ich ursprünglich dachte. Grundsätzlich haben Sie eine Seite, die nichts tut, bis die Daten, die Sie senden möchten, verfügbar sind (z. B. eine neue Nachricht eintrifft).
Hier ist ein wirklich einfaches Beispiel, das nach 2-10 Sekunden eine einfache Zeichenfolge sendet. 1: 3-Chance, einen Fehler 404 zurückzugeben (um die Fehlerbehandlung im kommenden Javascript-Beispiel zu zeigen)
msgsrv.php
<?php
if(rand(1,3) == 1){
/* Fake an error */
header("HTTP/1.0 404 Not Found");
die();
}
/* Send a string after a random number of seconds (2-10) */
sleep(rand(2,10));
echo("Hi! Have a random number: " . rand(1,10));
?>
Hinweis: Wenn Sie dies auf einer realen Site auf einem normalen Webserver wie Apache ausführen, werden schnell alle "Arbeitsthreads" gebunden, sodass andere Anfragen nicht beantwortet werden können. Es gibt Möglichkeiten, dies zu umgehen, es wird jedoch empfohlen, zu schreiben Ein "Long-Poll-Server" in so etwas wie Pythons Twisted , der nicht auf einen Thread pro Anfrage angewiesen ist. cometD ist ein beliebtes Framework (das in mehreren Sprachen verfügbar ist), und Tornado ist ein neues Framework, das speziell für solche Aufgaben entwickelt wurde (es wurde für FriendFeeds Code für lange Abfragen entwickelt). Als einfaches Beispiel ist Apache jedoch mehr als ausreichend ! Dieses Skript kann leicht in jeder Sprache geschrieben werden (ich habe Apache / PHP gewählt, da sie sehr häufig sind, und ich habe sie zufällig lokal ausgeführt).
Anschließend fordern Sie in Javascript die obige Datei ( msg_srv.php
) an und warten auf eine Antwort. Wenn Sie eine bekommen, reagieren Sie auf die Daten. Dann fordern Sie die Datei an und warten erneut, reagieren auf die Daten (und wiederholen)
Was folgt, ist ein Beispiel für eine solche Seite. Wenn die Seite geladen wird, sendet sie die erste Anforderung für die msgsrv.php
Datei. Wenn dies erfolgreich ist, #messages
hängen wir die Nachricht an das div an und rufen nach 1 Sekunde die Funktion waitForMsg erneut auf. was das Warten auslöst.
Die 1 Sekunde setTimeout()
ist ein wirklich grundlegender Ratenbegrenzer. Ohne diese Funktion funktioniert sie einwandfrei. Wenn sie jedoch msgsrv.php
immer sofort zurückgegeben wird (z. B. mit einem Syntaxfehler), wird der Browser überflutet und er kann schnell einfrieren. Dies sollte besser überprüft werden, ob die Datei eine gültige JSON-Antwort enthält, und / oder eine laufende Summe von Anforderungen pro Minute / Sekunde beibehalten und entsprechend angehalten werden.
Wenn die Seite fehlerhaft ist, hängt sie den Fehler an das #messages
div an, wartet 15 Sekunden und versucht es dann erneut (identisch damit, wie wir nach jeder Nachricht 1 Sekunde warten).
Das Schöne an diesem Ansatz ist, dass er sehr belastbar ist. Wenn die Internetverbindung des Clients unterbrochen wird, tritt eine Zeitüberschreitung auf. Versuchen Sie dann erneut, die Verbindung herzustellen. Dies hängt davon ab, wie lange das Abrufen funktioniert. Es ist keine komplizierte Fehlerbehandlung erforderlich
Wie auch immer, der long_poller.htm
Code, der das jQuery-Framework verwendet:
<html>
<head>
<title>BargePoller</title>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.2.6/jquery.min.js" type="text/javascript" charset="utf-8"></script>
<style type="text/css" media="screen">
body{ background:#000;color:#fff;font-size:.9em; }
.msg{ background:#aaa;padding:.2em; border-bottom:1px #000 solid}
.old{ background-color:#246499;}
.new{ background-color:#3B9957;}
.error{ background-color:#992E36;}
</style>
<script type="text/javascript" charset="utf-8">
function addmsg(type, msg){
/* Simple helper to add a div.
type is the name of a CSS class (old/new/error).
msg is the contents of the div */
$("#messages").append(
"<div class='msg "+ type +"'>"+ msg +"</div>"
);
}
function waitForMsg(){
/* This requests the url "msgsrv.php"
When it complete (or errors)*/
$.ajax({
type: "GET",
url: "msgsrv.php",
async: true, /* If set to non-async, browser shows page as "Loading.."*/
cache: false,
timeout:50000, /* Timeout in ms */
success: function(data){ /* called when request to barge.php completes */
addmsg("new", data); /* Add response to a .msg div (with the "new" class)*/
setTimeout(
waitForMsg, /* Request next message */
1000 /* ..after 1 seconds */
);
},
error: function(XMLHttpRequest, textStatus, errorThrown){
addmsg("error", textStatus + " (" + errorThrown + ")");
setTimeout(
waitForMsg, /* Try again after.. */
15000); /* milliseconds (15seconds) */
}
});
};
$(document).ready(function(){
waitForMsg(); /* Start the inital request */
});
</script>
</head>
<body>
<div id="messages">
<div class="msg old">
BargePoll message requester!
</div>
</div>
</body>
</html>