SorgenkindMech: Websockets / PHP

Mahlzeit!

Ich suche aktuell nach einer feinen Lösung mittels Websockets.

Ausgangssituation:
Es gibt einen Wochenplan, welcher alle paar Sekunden Aktualisierungen vom Server abfragt.
Diese Aktualisierungen können selbstverständlich von verschiedenen Benutzern stammen.

Nun würde ich das gern mittels Websockets lösen (alte Variante soll aus Kompatibilitätsgründen schon noch erhalten bleiben, quasi als fall-back)

System: IIS 8.5, PHP 5.5.8, WinCache

Soweit ich das verstanden habe, ist es zumindest bei PHP relativ egal ob nun der Webserver selbst Websockets unterstützt, im Prinzip muss ich selbst einen Socket öffnen mittels PHP ... sprich es läuft quasi immer ein PHP-Script, welches die eingehenden Verbindungen der Browser akzeptiert.
Dieses Script läuft ja nun erstmal nicht im Kontext des Webservers, sondern als CLI

nun ändert jemand etwas, was Auswirkung auf den wochenplan hat. Optimal wäre ja, wenn man nun aus der Webanwendung heraus dem laufenden Script signalisieren könnte "hey es hat sich was geändert, sende dies an alle deinen verbundenen Clients"

und genau hier sehe ich das Problem, ich wüsste nicht wie ...

die einzige Möglichkeit, die mir einfallen würde, dass das laufende script periodisch nach Änderungen selbst sucht, anstelle davon in Kenntnis gesetzt zu werden, und das ist dann schon wieder recht ineffektiv, auch wenn es zumindest schonmal den Vorteil hätte, dass nur ein script nach Änderungen sucht und nicht jeder Client für sich ....

hat jemand eine Idee, wie das gut umzusetzen wäre?

LG
euer SorgenkindMech

  1. hi SorgenkindMech,

    http://forum.de.selfhtml.org/archiv/2014/6/t217734/#m1496557 und Archivsuche nach Websockets ...;
    k.a. ob das auf Dein Problem passt.

    mfg

    tami

    1. hi SorgenkindMech,

      http://forum.de.selfhtml.org/archiv/2014/6/t217734/#m1496557 und Archivsuche nach Websockets ...;

      jup das hatte ich schon gesehen

      k.a. ob das auf Dein Problem passt.

      ähm ... nicht ganz ;)

      mfg

      tami

      aber dennoch danke ;)

  2. Meine Herren!

    nun ändert jemand etwas, was Auswirkung auf den wochenplan hat. Optimal wäre ja, wenn man nun aus der Webanwendung heraus dem laufenden Script signalisieren könnte "hey es hat sich was geändert, sende dies an alle deinen verbundenen Clients"

    Wenn deine Webanwendung dafür bisher keine Schnittstelle anbietet, musst du eben nachrüsten. Das Prinzip, das du damit verfolgst nennt sich "Inversion-Of-Control". Es gibt verschiedene Design-Pattern, die sich damit befassen: Publich/Subscribe oder Observer.

    Am schönsten wäre es, wenn du so eine Schnittstelle innerhalb deiner Webanwendung unterbringen könntest. Dazu müsstest du erstmal die Bausteine identifizieren, die wirklich mit der Änderung von Datensätzen zu tun haben. An diesen Stellen könntest du dann eine Ereignisbehandlung für andere Systeme anbieten. Dein WebSocket-Server würde sich zum Beispiel da einhaken.

    Wenn du an der alten Webanwendung keine Anpassungen mehr machen möchtest/kannst/darfst, dann kannst du hier eine neue Zwischenschicht einfügen. Diese Zwischenschicht ist dafür verantwortlich die Änderungen, die durch die Webanwendung vorgenommen werden, automatisiert zu erfassen und eine genormte Schnittstelle für fremde Systeme bereit zu stellen. Die automatische Erfassung der Änderungen ist allerdings komplizierter. Vielleicht bietet deine Datenbank-Schicht ja eine adäquate Lösung an, um auf Änderungen zu lauschen. Sonst bleibt dir wirklich nur noch das periodische Abfragen und Vergleichen mit dem jeweils letzen Zustand. Aber auch das wäre nicht weiter schlimm, denn durch so eine Zwischenschicht, werden diese zyklischen Statusabfragen nur noch von einem einzigen Akteur ausgeführt, der sie dann seinerseits auf elegantere Art weiter verbreitet. Es muss auf jedenfalls nicht mehr jedes Subsystem sich selbst um diesen Kram kümmern.

    Genug an abstrakten Erörterungen. Worauf basiert deine Webanwendung denn eigentlich? Irgend ein Framework, auf das deine Webanwendung aufsetzt? Welches Datenbanksystem nutzt du?

    --
    “All right, then, I'll go to hell.” – Huck Finn
    1. Meine Herren!

      Moin ;)

      Am schönsten wäre es, wenn du so eine Schnittstelle innerhalb deiner Webanwendung unterbringen könntest. Dazu müsstest du erstmal die Bausteine identifizieren, die wirklich mit der Änderung von Datensätzen zu tun haben. An diesen Stellen könntest du dann eine Ereignisbehandlung für andere Systeme anbieten. Dein WebSocket-Server würde sich zum Beispiel da einhaken.
      Genug an abstrakten Erörterungen. Worauf basiert deine Webanwendung denn eigentlich? Irgend ein Framework, auf das deine Webanwendung aufsetzt? Welches Datenbanksystem nutzt du?

      also das ganze ist eben in PHP / MySQL geschrieben.
      Der Kalender ist quasi eine Wochenansicht, oben die Wochentage, nach unten weg dann Tabellarisch Personen.
      Jede Person kann nun pro Tag verschiedene Einträge erhalten. Das können konkrete Termine, aber auch einfach nur Textbemerkungen sein

      bisher ist es so:

      es gibt ein allgemeines Protokoll, in dem die verschiedensten Aktivitäten geloggt werden (wer macht was)
      bestimmte Ereignisse, wie das Setzen eines Termines, das löschen eines Termines, die Aktivierung eines Termines, etc werden dann in einer SQL-Abfrage gefiltert.

      Aktuell fragt nun also der Clientbrowser alle paar Sekunden den Server mit Übergabe des letzten Nachfragezeitpunktes nach Änderungen

      Server macht nun eine SQL-Abfrage: suche alle Ereignisse vom Typ (...) dessen Zeitstempel über dem übermittelten Zeitstempel liegt. Das Ergebnis wird nun an den Clienten übermittelt.

      Sicher wäre es schon wesentlich besser, die periodische Abfrage nur zentral zu machen und dann an die Clients zu verteilen, aber noch besser wäre es ja, auf die periodische abfrage zu verzichten und eine Art Event zu Triggern, ich weiß nur nicht wie ;(

      wenn nun mein CLI-Script aka Websocket-Server läuft und parallel dazu nun beispielsweise ein Termin gesetzt wird, dann mache ich ja einen eintrag in der termintabelle und einen eintrag in der ereignistabelle ... so ... jetz könnte ich ja noch ein Trigger ansprechen, nur wie könnte dieser Trigger eine info an das CLI-Script senden? oder verbinde ich mich mit dem Websocketserver?

      Beispiel:
      Websocket-Server läuft auf Port 8080
      Clientbrowser verbindet sich und wartet auf Infos

      anderer Clientbrowser setzt Termin
      Server macht DB-Einträge, verbindet sich auf localhost:8080 und gibt info nun somit an den Websocket-Server

      Websocket-Server hat info und verteilt diese nun an die Clients ...

      hey das wäre doch eine lösung, ist diese auch praktikabel bzw. "schön"? ;)

      LG

      1. Meine Herren!

        Beispiel:
        Websocket-Server läuft auf Port 8080
        Clientbrowser verbindet sich und wartet auf Infos

        anderer Clientbrowser setzt Termin
        Server macht DB-Einträge, verbindet sich auf localhost:8080 und gibt info nun somit an den Websocket-Server

        Bis auf diesen einen Punkt, ist das ein eleganter Ansatz. Denn hier ensteht eine enge Kopplung zwischen Webserver und Socketserver. Der Webserver, muss wissen, wie er den Socketserver anspricht. Besser wäre, der Socketserver meldet sein Interesse »selbst« beim Server an und greift auf eine lose gekoppelte Schnittstelle zu. Deine Problematik habe ich jetzt erst richtig erfasst: WebServer und SocketServer laufen in verschiedenen Prozessen, deshalb kannst du nicht einfach eine PHP-Klasse modellieren, die ein Event-System bereitstellt. Der Austausch über Ereignisse muss auf eine andere Art stattfinden. Anbieten würde sich hier zum Beispiel ein Datei-Stream, in den deine Webanwendung schreibt, und auf den dein SocketServer lauscht. PHPs Möglichkeiten zur Implementierung einer asynchronen (nicht-blockierenden) Message-Queue sind aber mehr schlecht als recht. Vielleicht hilft dir ein Blick auf ein Framework, das sich genau mit dieser Problematik befasst.

        hey das wäre doch eine lösung, ist diese auch praktikabel bzw. "schön"? ;)

        Angesichts der beschränkten Kapazitäten von PHP in Hinblick auf nicht-blockierende Ereignisbehandlung, ist das vermutlich tatsächlich der praktische Ansatz, den man  gehen würde, wenn es nicht zu komplex werden soll.

        --
        “All right, then, I'll go to hell.” – Huck Finn
        1. Meine Herren!

          Beispiel:
          Websocket-Server läuft auf Port 8080
          Clientbrowser verbindet sich und wartet auf Infos

          anderer Clientbrowser setzt Termin
          Server macht DB-Einträge, verbindet sich auf localhost:8080 und gibt info nun somit an den Websocket-Server

          Bis auf diesen einen Punkt, ist das ein eleganter Ansatz. Denn hier ensteht eine enge Kopplung zwischen Webserver und Socketserver. Der Webserver, muss wissen, wie er den Socketserver anspricht.

          OK, da ich ja beiden selbst schreiben muss, würd ich das dem dann schon klar machen ;)

          Besser wäre, der Socketserver meldet sein Interesse »selbst« beim Server an und greift auf eine lose gekoppelte Schnittstelle zu.

          hätte ich dan nicht wieder latenzen, bzw. hätte ich dann nicht wieder regelmäßige abfragen innerhalb des Websocket-Servers?

          danke erst Mal bis hier hin ;)

          LG

          1. Meine Herren!

            anderer Clientbrowser setzt Termin
            Server macht DB-Einträge, verbindet sich auf localhost:8080 und gibt info nun somit an den Websocket-Server

            Bis auf diesen einen Punkt, ist das ein eleganter Ansatz. Denn hier ensteht eine enge Kopplung zwischen Webserver und Socketserver. Der Webserver, muss wissen, wie er den Socketserver anspricht.

            OK, da ich ja beiden selbst schreiben muss, würd ich das dem dann schon klar machen ;)

            Ja, ich glaube auch, dass das für deinen Fall der richtige Weg ist.

            Besser wäre, der Socketserver meldet sein Interesse »selbst« beim Server an und greift auf eine lose gekoppelte Schnittstelle zu.

            hätte ich dan nicht wieder latenzen, bzw. hätte ich dann nicht wieder regelmäßige abfragen innerhalb des Websocket-Servers?

            Ne, die gäbe es dann nicht. Der Webserver würde ein Ereignis in den Stream schreiben, das würde bei dem SocketServer, der sich bei diesem Stream angemeldet hat, sofort ein Ereignis auslösen und er könnte sofort darauf reagieren. Völlig ohne Polling. Das ist gerade die Philosophie hinter asynchronem I/O. Design-Pattern können hier wirklich sehr gut helfen, solche Prinzipien zu verstehen, das Observer-Pattern illustriert diesen "Inversion-Of-Control"-Gedanken imho. am besten.

            danke erst Mal bis hier hin ;)

            War eine interessante Frage ;) Da hilft man gerne. Viel Erfolg bei der Umsetzung.

            --
            “All right, then, I'll go to hell.” – Huck Finn