Seite 1 von 2

Server im Http-Server ;)

Verfasst: Dienstag 29. April 2008, 19:42
von Jan.O
Hi,

Ich werde meine Frage anhand eines Chatservers als Beispiel erläutern.

Es sieht so aus: Ein Benutzer der Website hat eine seite geöffnet. Die website ist komplett in python programmiert, läuft jedoch unter einem HTTP-Server eurer wahl (zB mit fastcgi)

Hier die Herausforderung: Wenn ein Benutzer eine Chatnachricht sendet, soll diese automatisch an alle clients gebroadcastet werden.

Aktuelle Lösung: Es gibt einen externen server, mit dem sich jeder "Seitenaufruf" verbindet.

Lässt sich das Problem auch ohne zusätzliche Socket-Verbindung lösen? Kann man den Server also direkt im HTTP-Server impelemtieren? Es handelt sich ja im prinzip um eine Art Variablen-Sharing.

Re: Server im Http-Server ;)

Verfasst: Dienstag 29. April 2008, 20:03
von lunar
Jan.O hat geschrieben:Aktuelle Lösung: Es gibt einen externen server, mit dem sich jeder "Seitenaufruf" verbindet. Dann wird über einen socket an diese clients gebroadcasted.
HTTP unterstützt keine Push-Prozesse. Das wäre auch gar nicht möglich, da HTTP zustandslos ist und per definitionem keine Verbindung zum Client hält, nach dem der Response abgeschlossen ist. Alle Client müssen die Änderungen einer Website manuell(!) holen.

Entweder "fakst" du PUSH-Szenarien, indem du mit Javascript oder HTML-Meta-Refreshs die Seite periodisch neu lädst (was entsprechend hohe Serverlast zur Folge hat) oder du musst dir mit externen Technologien behelfen. Java-Applets, Flash-Programme, und mittlerweile auch Silverlight wären so Dinge, die man dafür (miss-)brauchen könnte. Ansonsten bleibt dir natürlich dein bisheriger Weg (den ich allerdings nicht ganz verstanden habe ;) )

Verfasst: Dienstag 29. April 2008, 20:13
von Jan.O
Es ist ohne Weiteres möglich die http-verbindung nach senden der HTML-Struktur aufrecht zu erhalten und nachträglich javascript-befehle im <script>-Tag nachzusenden. Getestet mit PHP in den IEs, FF und Opera.

Verfasst: Dienstag 29. April 2008, 22:39
von Y0Gi
HTTP-Keep-Alive und asynchrones Pollen sind trotzdem noch kein Push.

Verfasst: Dienstag 29. April 2008, 22:51
von Jan.O
Y0Gi hat geschrieben:HTTP-Keep-Alive und asynchrones Pollen sind trotzdem noch kein Push.
Ich spreche tatsächlich nicht von einer HTTP-Keep-Alive verbindung sondern von einer aufrechtgehaltenen Socketverbindung zwischen webserver und browser, was das nachträgliche senden von scriptbefehlen möglich macht.

Verfasst: Dienstag 29. April 2008, 23:55
von mitsuhiko
Gehen tut das schon, aber schön und praktisch ist das nicht: http://dev.pocoo.org/hg/sandbox/file/10 ... ingchat.py

Verfasst: Mittwoch 30. April 2008, 09:49
von sma
Hm, ich habe wohl zu lange Java gemacht, denn mein erster Implus bei Jan.Os Fragen ist immer, auf Java und die Möglichkeiten dort hinzuweisen. Wäre Flash & AMF eine Alternative? Dann wäre PyAMF vielleicht einen Blick wert. Schon aus dem Grund, als das mich das interessieren würde... Was allerdings auch nicht schlecht aussah, war Orbited.

Jedenfalls brauchst du wohl einen eigenen externen Server, da Python-Webrahmenwerke in der Regel ja Request-basiert ("share nothing") arbeiten und nicht aus einem Application Server (wie bei Java) arbeiten. Es gibt zwar mit CherryPy und Paste zwei Standalone-Server, doch sie werden irgendwie selten empfohlen, sodass ich hier das Vorurteil hätte, dass das nicht gut skaliert.

Und dann ist da natürlich noch Zope... verdammt, ich muss da dringend mehr drüber lernen, denn sagen kann ich dazu gar nichts, außer dass das ein Application Server wäre (Google nach Comet+Zope befragt gibt aber keine überzeugenden Hits).

Stefan

Verfasst: Mittwoch 30. April 2008, 09:58
von Leonidas
Ich würde auch wohl als erstes mal Comet ausprobieren, muss zugeben, dass ich es noch nicht benutzt habe. Teilweise auch darum, weil Webchats sowieso eine kranke Idee sind.

Und ja, Zope skaliert nicht wirklich. Zumindest Zope 2 hat deutlich bessere Hardware gebraucht, um zu laufen, als normale Frameworks. Dafür bietet es auch mehr, zugegeben.

Verfasst: Mittwoch 30. April 2008, 10:30
von Y0Gi
Jan.O hat geschrieben:Ich spreche tatsächlich nicht von einer HTTP-Keep-Alive verbindung sondern von einer aufrechtgehaltenen Socketverbindung zwischen webserver und browser, was das nachträgliche senden von scriptbefehlen möglich macht.
Da habe ich mich wohl zu sehr an
Jan.O hat geschrieben:[...] an alle clients gebroadcastet werden, die gerade eine http-Verbindung aufrecht erhalten.
festgehalten. Wenn du natürlich parallel eine Socket-Verbindung aufbaust/aufrecht erhältst, hat das wenig (as in: nichts mehr) mit HTTP zu tun. Angesichts von HTTP-Proxies, Routern und (Personal) Firewalls dürfte so ein Ansatz in breiter Anwendung vermutlich zum Scheitern verurteilt sein, weil speziell auch der Browser mit sowas nicht umgehen kann oder will.
Ausnahmen sind hier Browser-Plugins mit Sandbox, wie ja schon genannt, eben Flash, ActiveX und Java. Bis auf Flash sehe ich da allerdings keine Zukunft; und heutzutage einen simplen Chat als Java-Applet unters Volk bringen zu wollen, erscheint mir schon fast irrwitzig.

Ich denke nicht, dass es eine Frage des Web-Frameworks auf Serverseite ist, sondern des/der eingesetzten Protokolls/e.

P.S.: Ich bin mal über einen Chat-PoC gestolpert, bei dem ein dynamisch erzeugtes PNG mit Chat-Nachrichten über eine aufrecht erhaltene Verbindung und längere Zeit zeilenweise an den Client geliefert wird, der es dann nach und nach anzeigt ;)

Verfasst: Mittwoch 30. April 2008, 14:38
von Jan.O
Ersteinmal: Ich will keinen Chat programmieren. Ich beziehe mich nur auf das beispiel eines Chats, um das Problem besser darstellen zu können.
Y0Gi hat geschrieben:
Jan.O hat geschrieben:Ich spreche tatsächlich nicht von einer HTTP-Keep-Alive verbindung sondern von einer aufrechtgehaltenen Socketverbindung zwischen webserver und browser, was das nachträgliche senden von scriptbefehlen möglich macht.
Da habe ich mich wohl zu sehr an
Jan.O hat geschrieben:[...] an alle clients gebroadcastet werden, die gerade eine http-Verbindung aufrecht erhalten.
festgehalten. Wenn du natürlich parallel eine Socket-Verbindung aufbaust/aufrecht erhältst, hat das wenig (as in: nichts mehr) mit HTTP zu tun. Angesichts von HTTP-Proxies, Routern und (Personal) Firewalls dürfte so ein Ansatz in breiter Anwendung vermutlich zum Scheitern verurteilt sein, weil speziell auch der Browser mit sowas nicht umgehen kann oder will.
Ausnahmen sind hier Browser-Plugins mit Sandbox, wie ja schon genannt, eben Flash, ActiveX und Java. Bis auf Flash sehe ich da allerdings keine Zukunft; und heutzutage einen simplen Chat als Java-Applet unters Volk bringen zu wollen, erscheint mir schon fast irrwitzig.
Die HTTP-Verbindung ist ja auch nur eine Socket-Verbindung. Und ich spreche davon, DIESE aufrecht zu erhalten. Keep-Alive ist so ähnlich, allerdings ist der Transfer der Website normalerweise irgendwann abgeschlossen und es können keine weiteren daten mehr übermittelt werden.

Und das geht auch.
Jan.O hat geschrieben:Es ist ohne Weiteres möglich die http-verbindung nach senden der HTML-Struktur aufrecht zu erhalten und nachträglich javascript-befehle im <script>-Tag nachzusenden. Getestet mit PHP in den IEs, FF und Opera.
Das sind mehr als 98% aller Benutzer. Ich habe ohne probleme mehrere stunden lang script-befehle nachgesendet

@Leonidas Vielen Dank für den Tipp mit Comet! Werde ich mir mal angucken.

Verfasst: Donnerstag 1. Mai 2008, 14:11
von Y0Gi
Leider habe ich nicht die leiseste Vorstellung von dem, was du mit "Script-Befehlen" meinst.

Hast du für das (wie ich es verstanden habe) nachträgliche Hijacken des HTTP-Sockets Beispielcode?

Verfasst: Donnerstag 1. Mai 2008, 14:55
von Trundle
Y0Gi hat geschrieben:Leider habe ich nicht die leiseste Vorstellung von dem, was du mit "Script-Befehlen" meinst.
Etwas in der Art eben:

Code: Alles auswählen

from time import sleep

def http_abuse(environ, start_response):
    start_response('200 OK', [('Content-Type', 'text/html')])
    yield '<html><title>Tolle Seite</title><body>'
    while True:
        sleep(1)
        yield '<script>alert("I\'m still alive");</script>'

Verfasst: Donnerstag 1. Mai 2008, 15:00
von Y0Gi
Ah! Das gehört dann aber doch noch zum selben und einzigen HTTP-Request?

Verfasst: Donnerstag 1. Mai 2008, 15:06
von mitsuhiko
.oO( Hat sich eigentlich irgendjemand mein Beispiel angesehen? )

Verfasst: Donnerstag 1. Mai 2008, 15:12
von Trundle
mitsuhiko hat geschrieben:.oO( Hat sich eigentlich irgendjemand mein Beispiel angesehen? )
Ja, und einen rudimentären IRC-Client damit gebaut -.-

Verfasst: Freitag 2. Mai 2008, 10:31
von Y0Gi
mitsushiko: Ja, aber erst jetzt hab' ich's irgendwie verstanden.

Gibt es dabei irgendwelche Limitierungen*, z.B. kann diese Verbindung "unendlich lange" aufrecht erhalten werden?

Was genau macht Comet anders?

Gibt es bessere Ansätze? Scheinbar ja nicht ...


*) Ok, mal abgesehen davon, dass ich den Server hier abschießen muss und nicht mehr normal beenden kann.

Verfasst: Freitag 2. Mai 2008, 15:08
von Jan.O
Y0Gi hat geschrieben: Gibt es dabei irgendwelche Limitierungen*, z.B. kann diese Verbindung "unendlich lange" aufrecht erhalten werden?
Ja

Wäre cool, wenn sich noch mal jemand zur ursprünglichen Frage äußern könnte, wie ich jetzt daten an alle geöffneten http-clients broadcasten könnte

Verfasst: Freitag 2. Mai 2008, 16:49
von Y0Gi
Broadcasten in dem Sinne kann es ja schon nicht sein, da du zu jedem Client einen eigenen Socket hast.

Ich würde versuchen, die WSGI-Callable nach dem eigentlichen XHTML-Dokument weitere Daten aus einem Iterable holen zu lassen, das allen Instanzen zur Verfügung steht, entsprechend thread-safe sein müsste und aus dem pro Request/Socket jedes Element nur einmal gelesen wird. Notfalls könnte man für die aktiven Client-Verbindungen eine Liste von ``Queue``-Objekten bereithalten (was dann aber z.B. einen separaten Thread erfordert) und jedes bei vorliegenden Daten füttern, die der Client sich abholt.

Jan.O hat geschrieben:
Y0Gi hat geschrieben: Gibt es dabei irgendwelche Limitierungen*, z.B. kann diese Verbindung "unendlich lange" aufrecht erhalten werden?
Ja
Dann kannst du sie mir ja auch kurz ausführen. Auch wenn (oder gerade weil) es etwas abgeschweift ist (oder so scheint), sollten wir das zu einem brauchbaren Ende bringen.

Davon ab hätte ich mich ohne die Ausführungen anhand deiner, naja, etwas abstrakt formulierten Problemstellung nicht in das hineinversetzen können, was du vorhast.

Verfasst: Freitag 2. Mai 2008, 17:58
von Jan.O
Das "ja" bezog sich auf den 2. Teil: Die verbindung kann "unendlich" lange aufrecht erhalten werden.

Verfasst: Freitag 2. Mai 2008, 18:07
von mitsuhiko
[strong]X[/strong]HTML streamen ist eine schlechte Idee weil ältere Browser XHTML Dokumente nur dann rendern können, wenn sie die komplett geladen haben. Zb Firefox 2.