809 Stimmen

Wie führe ich ein einfaches "Long Polling" durch?

Ich kann viele Informationen darüber finden, wie Long Polling funktioniert (zum Beispiel, este y este ), aber keine einfach Beispiele, wie dies in Code umgesetzt werden kann.

Alles, was ich finden kann, ist cometd die auf dem Dojo JS-Framework und einem ziemlich komplexen Serversystem basiert.

Wie würde ich Apache verwenden, um die Anfragen zu bedienen, und wie würde ich ein einfaches Skript (z. B. in PHP) schreiben, das den Server nach neuen Nachrichten "abfragt"?

Das Beispiel muss nicht skalierbar, sicher oder vollständig sein, es muss nur funktionieren!

9voto

brightball Punkte 885

Dies ist eines der Szenarien, für die PHP eine sehr schlechte Wahl ist. Wie bereits erwähnt, können Sie auf diese Weise sehr schnell alle Ihre Apache-Arbeitsgruppen blockieren. PHP ist für Start, Ausführung, Stopp ausgelegt. Es ist nicht für Starten, Warten, Ausführen, Stoppen gemacht. Sie werden Ihren Server sehr schnell lahm legen und unglaubliche Skalierungsprobleme haben.

Das heißt, Sie können immer noch tun dies mit PHP und haben es nicht töten Ihren Server mit dem nginx HttpPushStreamModule: http://wiki.nginx.org/HttpPushStreamModule

Sie richten nginx vor Apache (oder was auch immer) ein und es kümmert sich darum, die gleichzeitigen Verbindungen offen zu halten. Man antwortet einfach mit Payload, indem man Daten an eine interne Adresse sendet, was man mit einem Hintergrundjob machen könnte, oder man schickt die Nachrichten einfach an die Leute, die warten, wenn neue Anfragen reinkommen. Dadurch wird verhindert, dass PHP-Prozesse während langer Abfragen offen bleiben.

Dies ist nicht auf PHP beschränkt und kann mit nginx mit jeder Backend-Sprache durchgeführt werden. Die Last der gleichzeitig geöffneten Verbindungen entspricht der von Node.js, sodass der größte Vorteil darin besteht, dass man Node für so etwas nicht mehr benötigt.

Sie sehen viele Leute, die andere Sprachbibliotheken für die Durchführung langer Abfragen erwähnen, und das aus gutem Grund. PHP ist einfach nicht gut für diese Art von Verhalten natürlich gebaut.

8voto

xoblau Punkte 89

Vielen Dank für den Code, dbr . Nur ein kleiner Tippfehler in long_poller.htm um die Linie

1000 /* ..after 1 seconds */

Ich denke, es sollte sein

"1000"); /* ..after 1 seconds */

damit es funktioniert.

Für diejenigen, die es interessiert, habe ich ein Django-Äquivalent ausprobiert. Starten Sie ein neues Django-Projekt, sagen wir lp für lange Abfragen:

django-admin.py startproject lp

Aufruf der App msgsrv für Nachrichten-Server:

python manage.py startapp msgsrv

Fügen Sie die folgenden Zeilen hinzu einstellungen.py zu haben Vorlagen Verzeichnis:

import os.path
PROJECT_DIR = os.path.dirname(__file__)
TEMPLATE_DIRS = (
    os.path.join(PROJECT_DIR, 'templates'),
)

Definieren Sie Ihre URL-Muster in urls.py als solche:

from django.views.generic.simple import direct_to_template
from lp.msgsrv.views import retmsg

urlpatterns = patterns('',
    (r'^msgsrv\.php$', retmsg),
    (r'^long_poller\.htm$', direct_to_template, {'template': 'long_poller.htm'}),
)

Und msgsrv/ views.py aussehen sollte:

from random import randint
from time import sleep
from django.http import HttpResponse, HttpResponseNotFound

def retmsg(request):
    if randint(1,3) == 1:
        return HttpResponseNotFound('<h1>Page not found</h1>')
    else:
        sleep(randint(2,10))
        return HttpResponse('Hi! Have a random number: %s' % str(randint(1,10)))

Schließlich, Vorlagen/ long_poller.htm sollte dasselbe sein wie oben, wobei der Tippfehler korrigiert wurde. Ich hoffe, das hilft.

4voto

shasi kanth Punkte 6787

Warum nicht die Web-Sockets anstelle von langen Abfragen in Betracht ziehen? Sie sind sehr effizient und einfach einzurichten. Allerdings werden sie nur von modernen Browsern unterstützt. Hier ist ein Schnellreferenz .

3voto

makerofthings7 Punkte 57238

Die WS-I-Gruppe hat ein Dokument namens "Zuverlässiges und sicheres Profil" mit einem Glasfisch und .NET-Implementierung die offenbar interoperabel nun ja.

Mit etwas Glück gibt es eine Javascript Umsetzung auch da draußen.

Es gibt auch eine Silverlight-Implementierung, die die HTTP-Duplex. Sie können Javascript mit Silverlight verbinden Objekt, um Rückrufe zu erhalten, wenn ein Push stattfindet.

Außerdem gibt es kommerzielle kostenpflichtige Versionen auch.

2voto

ideawu Punkte 2189

Sie können es mit icomet( https://github.com/ideawu/icomet ), ein C1000K C++ Comet-Server, der mit libevent gebaut wurde. icomet stellt auch eine JavaScript-Bibliothek zur Verfügung, die so einfach zu benutzen ist wie

var comet = new iComet({
    sign_url: 'http://' + app_host + '/sign?obj=' + obj,
    sub_url: 'http://' + icomet_host + '/sub',
    callback: function(msg){
        // on server push
        alert(msg.content);
    }
});

icomet unterstützt eine breite Palette von Browsern und Betriebssystemen, einschließlich Safari (iOS, Mac), IEs (Windows), Firefox, Chrome, etc.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X