Matze: viele, viele Requests oder doch ganz einfach?

Hallo!

Ich möchte den aktuellen Status eines Projektes grafisch auf einer Seite darstellen.
Dazu wird ein Balken erstellt der kontinuierlich abnimmt. Z.B. innerhalb von 10min von 100% auf 0%. Dieser Zeitraum beschreibt die Dauer des Projekts.

Der Benutzer soll nun durch drücken verschiedener Buttons Einfluss auf diesen Timer nehmen. Gleichzeitig soll, bei erfolgreicher Manipulation, allen anderen Benutzern dies sofort mitgeteilt werden.

Beispiel: Benutzer drückt auf einen + Button, dem Projekt wird 5min mehr Zeit spendiert. Der grafische Balken soll daraufhin sofort bei allen Benutzern den neuen Prozentwert anzeigen. Jetzt also x% von 15min vergangen.

Jetzt hapert es allerdings ein wenig an der Umsetzung.
Es sollte wohl möglich sein, jede Sekunde einen AJAX-Request an den Server zu schicken um die aktuellen Daten zu erhalten.
Das stell ich mir aber sehr Serverlastig vor. Und dazu kommt noch, dass das dann immernoch nicht wirklich eine Reaktion auf gemachte Änderungen ist.

Meine Überlegung war jetzt, wo man so etwas noch antrifft und mir ist ein Chat eingefallen. Benutzer machen Eingaben und alle anderen Benutzer bekommen dies mitgeteit. Das Problem ist aber, dass ein Chat 'normalerweise' nicht auf http aufsetzt und ich von den Java(Script)-Chats keine Ahnung habe.

Meine Frage ist jetzt also wie ich das umsetzen kann.
Also dass alle bestimmten Aktionen eines Benutzers an alle anderen weitergereicht werden und ein Traffic-Chaos vermieden wird.
Dasselbe gilt dann natürlich für die Belastung der Datenbank in die neue Werte geschrieben bzw ausgelesen werden müssen.

Jemand einen Schubs in die richtige Richtung?

Danke und Grüße, Matze

  1. moin,

    Es sollte wohl möglich sein, jede Sekunde einen AJAX-Request an den Server zu schicken um die aktuellen Daten zu erhalten.

    Eine sekunde ist sehr knapp. Über heutige Breitbandverbindungen liegt zwar die Laufzeit Request-Response einschließlich des Startens eines serverseitigen Prozesses (der die Reponse erzeugt) deutlich unter 1 s (sagen wir 500 ms), bedenke jedoch, dass das Starten eines serverseitigen Prozesses (CGI) den Server schnell in die Knie zwingen kann bei vielen Anfragen. Letzteren Overhead könntest Du vermeiden mit FastCGI, d.h. der Serverprozess läuft schon und muss nicht erst jedesmal gestartet werden.

    Jemand einen Schubs in die richtige Richtung?

    Meine Überlegungen gehen in Richtung Broadcast oder Multicast und UDP. Broadcast: Client a sendet eine Zustandsänderung (Trap) an alle Clients [oder Multicast an Clients a-z] und nicht an den Server. Das heißt jedoch, dass es auf den Clients einen Agent geben muss, also auch sowas wie ein Server (Listen on Port xy). UDP anstelle TCP: Es wird ein Datagram gesendet, ohne eine Response zu erwarten.

    Hotti

    1. Hey!

      Jemand einen Schubs in die richtige Richtung?

      Das heißt jedoch, dass es auf den Clients einen Agent geben muss, also auch sowas wie ein Server [..]

      Ja und genau das ist das Problem. Das muss nämlich vermieden werden.
      Ist sowas vielleicht mit Flash möglich?
      Ich weiß nicht wie das mit dem Streamen von Dateien läuft, aber es ist ja auch möglich Filme über Flash-Player zu schauen ohne dass dazu erst der ganze Film auf dem Rechner liegen muss. Der Player muss also auch irgendwie mit dem Server in Verbindung bleiben.

      Grüße, Matze

      1. h1,

        Ja und genau das ist das Problem. Das muss nämlich vermieden werden.
        Ist sowas vielleicht mit Flash möglich?

        Oooops, da muss ich auch erstmal nachlesen. Also das was ich da schrieb, geht runter bis auf Layer 4 (UDP)....

        Ich weiß nicht wie das mit dem Streamen von Dateien läuft,

        Ungefär so: Betrachte einen Stream als eine Datei ohne EOF, als eine endlos-Datei. Nun gibt es da Player, die lesen eine Datei ersteinmal ein bis EOF, stellen die Länge fest und lesen evntl. den id3 Tag, der kurz vor EOF notiert ist (id3 kann aber auch am Anfang der Datei stehen).

        Ein Player hingegen, der einen (endlos) Stream spielen kann, wird den Stream nicht bis EOF lesen, logisch es gibt ja auch kein EOF (End of File). Ein solcher Player wird, nachdem er ein stückweit die bytes gelesen hat, sofort mit dem Abspielen beginnen und je nach Codec sukzessive weitere bytes einlesen und abspielen. Der Player frisst sich sozusagen durch den Stream ;-)

        Ein Codec wäre sowas wie mp3. Ein streamfähiger P. wird nach dem Starten einen Stream soweit lesen, bis er den Codec erkennt, wo drinsteht, wie die Daten komprimiert sind und in welchem Tempo die abzuspielen sind.

        Hotti

  2. Es sollte wohl möglich sein, jede Sekunde einen AJAX-Request an den Server zu schicken um die aktuellen Daten zu erhalten.

    Ein anderer Ansatz wäre, auf dem Server ein beliebiges, kleines Image zu hinterlegen. Seine Höhe (oder Breite) in Pixeln entspricht dem gewünschten Wert.

    Alle User holen sich im 5-sec-Takt das Bild und werten die Höhe (Breite) aus. Dabei ist zu beachten, dass dem Bildnamen ein wechselnder Parameter angehängt wird, sonst nimmt der Browser das Bild aus seinem Cache.

    Wenn ein User den Wert ändert, wird ein neues Bild gleichen Namens erzeugt, das dann spätestens 5 sec. später jeder andere User hat.

    MfG Kalle

    1. Hi!

      Es sollte wohl möglich sein, jede Sekunde einen AJAX-Request an den Server zu schicken um die aktuellen Daten zu erhalten.
      Ein anderer Ansatz wäre, auf dem Server ein beliebiges, kleines Image zu hinterlegen. Seine Höhe (oder Breite) in Pixeln entspricht dem gewünschten Wert.

      Wenn du sowieso einen Poll-Request erzeugst, kannst du auch einen Wert im JSON-Format zurück liefern lassen, und musst ihn nicht über das Vehikel Bildressource transportieren. Das ist wesentlich entspannter auf dem Server zu erstellen als auch auf dem Client zu lesen.

      Lo!

    2. Hey!

      Wenn ein User den Wert ändert, wird ein neues Bild gleichen Namens erzeugt, das dann spätestens 5 sec. später jeder andere User hat.

      Zu dedlfix Einwand auch noch der Hinweis, dass mir 5 Sekunden zu lang sind.
      Mit 1 Sekunde könnte ich wohl leben, aber das scheint mir wie gesagt, doch sehr zu Lasten des Servers zu gehn.

      Die Idee mit dem Image bringt mich aber auf die Idee, bei einer Änderung bzw. beim Start des Projekts eine Datei zu Erstellen o. ggf. zu ändern.
      Die könnte man dann im Abrufverfahren auslesen und müsste nicht zusätzlich die Datenbank belasten.

      Das wäre schonmal ein schönes Stück näher an der Optimierung denk ich.

      Grüße, Matze

  3. Guten Morgen,

    [...]
    Meine Überlegung war jetzt, wo man so etwas noch antrifft und mir ist ein Chat eingefallen. Benutzer machen Eingaben und alle anderen Benutzer bekommen dies mitgeteit. Das Problem ist aber, dass ein Chat 'normalerweise' nicht auf http aufsetzt und ich von den Java(Script)-Chats keine Ahnung habe.

    Eine Möglichkeit (für die meistens ein Chat der Standardbeispielfall ist) wäre eine Comet-Architektur (http://alex.dojotoolkit.org/2006/03/comet-low-latency-data-for-the-browser/). Dabei schließt der Server den Request nicht ab, sondern hält ihn offen und kann dadurch beliebig Daten nachschieben. Der Client muss damit dann halt umgehen können. Diese Art von Request/Response wird oft in Verbindung mit AJAX eingesetzt, wobei der Seitenrahmen komplett geladen wird, um dann mit einem zweiten Request (Javascript) die offene Kommunikation mit dem Server zu starten.
    In Servlet 3.0 ist diese Möglichkeit spezifiziert. Ob und welche Möglichkeiten es da mit PHP o.Ä. gibt, kann ich Dir nicht sagen.

    Schöne Grüße,

    Peter

    1. Hey Peter!

      Eine Möglichkeit (für die meistens ein Chat der Standardbeispielfall ist) wäre eine Comet-Architektur (http://alex.dojotoolkit.org/2006/03/comet-low-latency-data-for-the-browser/). Dabei schließt der Server den Request nicht ab, sondern hält ihn offen und kann dadurch beliebig Daten nachschieben. Der Client muss damit dann halt umgehen können. Diese Art von Request/Response wird oft in Verbindung mit AJAX eingesetzt, wobei der Seitenrahmen komplett geladen wird, um dann mit einem zweiten Request (Javascript) die offene Kommunikation mit dem Server zu starten.
      In Servlet 3.0 ist diese Möglichkeit spezifiziert. Ob und welche Möglichkeiten es da mit PHP o.Ä. gibt, kann ich Dir nicht sagen.

      Wow, das hört sich sehr vielversprechend und allgemein sehr nützlich an.
      Jetzt muss ich nur noch rausfinden, ob es sowas auch für PHP oder zur Not vllt. CGI gibt.
      Wenn du noch weitere Informationen dazu hast, nur her damit! Das gefällt mir wirklich.
      Da würde ich mich doch ziemlich ärgern wenn das mit z.B. PHP nicht umzusetzen ist.

      Danke und Grüße, Matze

      1. Hi!

        Eine Möglichkeit (für die meistens ein Chat der Standardbeispielfall ist) wäre eine Comet-Architektur (http://alex.dojotoolkit.org/2006/03/comet-low-latency-data-for-the-browser/). Dabei schließt der Server den Request nicht ab, sondern hält ihn offen und kann dadurch beliebig Daten nachschieben.
        Jetzt muss ich nur noch rausfinden, ob es sowas auch für PHP oder zur Not vllt. CGI gibt.

        Das ist prinzipell auch mit PHP zu machen. Um Informationshäppchen gleich nach der Erzeugung zum Client zu befördern, kann man mit flush() den Webserver bitten, seinen Puffer sofort in Richtung Client zu entleeren und nicht erst das Paket vollzupacken. Das nächste Problem sind Laufzeitbegrenzer, die nach verbrauchter CPU-Zeit die Abarbeitung einstellen. Da wäre als erstes PHPs max_execution_time zu nennen und als weitere Option Prozessüberwacher, wie sie bei 1&1 zum Einsatz kommen. Da wird von außen der Prozess beendet, egal, wie man max_execution_time einstellt.

        Lo!

        1. Hey dedlfix!

          Das ist prinzipell auch mit PHP zu machen. Um Informationshäppchen gleich nach der Erzeugung zum Client zu befördern, kann man mit flush() den Webserver bitten, seinen Puffer sofort in Richtung Client zu entleeren und nicht erst das Paket vollzupacken. Das nächste Problem sind Laufzeitbegrenzer, die nach verbrauchter CPU-Zeit die Abarbeitung einstellen. Da wäre als erstes PHPs max_execution_time zu nennen und als weitere Option Prozessüberwacher, wie sie bei 1&1 zum Einsatz kommen. Da wird von außen der Prozess beendet, egal, wie man max_execution_time einstellt.

          Leider ist mir dasselbe in den Sinn gekommen.
          max_execution_time müsste deaktiviert sein. Das bedeutet, dass ich Serverzugriff haben muss.
          Dann kann ich mich aber eigentlich auch gleich mit Java beschäftigen.
          Bzw mit einem Java-Server, JSP.

          Nach kurzem suchen bin ich auf https://glassfish.dev.java.net/ gestossen. Das scheint ein guter Anfang zu sein.

          Grüße, Matze

          1. Guten Morgen,

            [...]
            Leider ist mir dasselbe in den Sinn gekommen.
            max_execution_time müsste deaktiviert sein. Das bedeutet, dass ich Serverzugriff haben muss.

            Neben dem Request-Timeout ist auch die Anzahl der geblockten Threads im Server zu berücksichtigen. In der Regel kann nur eine begrenzte Anzahl an Threads mit einer Netzwerkverbindung aufgemacht werden. Wenn diese Anzahl an "Lauschern" erreicht ist, würde der Server keine neuen Verbindungen mehr annehmen.
            In Java wird hier ein Thread-Pooling-Ansatz gewählt, bei dem gerade inaktive Verbindungen (die nichts senden müssen) im Pool vorgehalten werden und damit keine aktive Connection verbrauchen.

            Dann kann ich mich aber eigentlich auch gleich mit Java beschäftigen.
            Bzw mit einem Java-Server, JSP.

            Nach kurzem suchen bin ich auf https://glassfish.dev.java.net/ gestossen. Das scheint ein guter Anfang zu sein.

            Mit dem Glassfish kann man schon recht viele Sachen machen, allerdings ist er halt nur die Ausführungsplattform. Das ultimative Nachschlagewerk ist die JSP / Servlet Spezifikation 3.0 http://jcp.org/en/jsr/detail?id=315, das Sun Java EE Tutorial http://java.sun.com/javaee/6/docs/tutorial/doc/ und die Dokumente unter glassfish.dev.java.net.

            Viel Erfolg!

            Peter

          2. Hi!

            max_execution_time müsste deaktiviert sein. Das bedeutet, dass ich Serverzugriff haben muss.

            Nicht zwangsläufig. Auch im Script lässt sich max_execution_time prinzipiell ändern. Ob der Hoster Gegenmaßnahmen ergriffen hat, steht auf einem anderen Blatt.

            Dann kann ich mich aber eigentlich auch gleich mit Java beschäftigen.

            Und wer stellt dir Java serverseitig zur Verfügung? Zu welchem Preis, und was kostet es, einen eigenen Server mit PHP zu betreiben?

            Lo!

            1. Hey dedlfix!

              Und wer stellt dir Java serverseitig zur Verfügung? Zu welchem Preis, und was kostet es, einen eigenen Server mit PHP zu betreiben?

              Also zunächst einmal würde ich ja lokal entwickeln und dafür reicht z.B. Tomcat. Das ist kostenlos. Dazu eine Datenbank die der XAMPP bereits mit sich bringt und einen Editor. Ich habe das Glück (ja, ich seh das so), eine legale Vollversion vom Dreamweaver zu besitzen, also dürfte da auch kein Problem entstehen.

              Liege ich soweit richtig?

              Es ist so, dass ich von JAVA wirklich 0 Ahnung habe und mein Vorhaben liebend gern mit PHP umsetzen würde. Ich finde dort aber keinen Ansatz weil PHP für derartige Dynamic wohl nicht ausgelegt ist.

              Grüße, Matze

              1. Hi!

                Und wer stellt dir Java serverseitig zur Verfügung? Zu welchem Preis, und was kostet es, einen eigenen Server mit PHP zu betreiben?
                Also zunächst einmal würde ich ja lokal entwickeln [...]

                Und dann?

                Wenn du nur lokal bleiben willst, kannst du dir ja auch dein PHP und Apachen entsprechend locker konfigurieren.
                Wenn du später an die Öffentlichkeit gehen willst, musst du stets die Gegebenheiten des Produktivsystems berücksichtigen.

                Lo!