Ankündigung

Einklappen
Keine Ankündigung bisher.

Read: Wie funktioniert das mit dem Index?

Einklappen
X
 
  • Filter
  • Zeit
  • Anzeigen
Alles löschen
neue Beiträge

    #16
    Zitat von tuxedo Beitrag anzeigen
    Gibt's schon Erfahrungswerte ob das mit SSE insgesamt besser/stabiler/zuverlässiger/schneller läuft?
    Lass es mich mal anders sagen:

    Die Datenrate auf dem KNX ist so langsam, dass klassisches Long Polling bei weitem nicht an die Grenze kommt.

    => Lohnt es sich hier zu optimieren?

    Warum klassisches Long Polling verwendet wird ist auch ganz simpel erklärt: es gab damals nichts anderes (und meines Wissens nach ist die CometVisu die erste echteiztfähige rein Web basierte Visu!) und nutzt so weit verbreitete und folglich kompatible und implementierte Technologie.
    Inzwischen sind fünf Jahre vergangen, Firefox nicht mehr bei Version 3.6 (sondern bei 41).
    D.h. hier eine weitere, optimierte Schnittstelle zu den Daten zu verwenden macht durchaus Sinn. Notwendig ist es aber nicht zwingend.
    TS2, B.IQ, DALI, WireGate für 1wire so wie Server für Logik und als KNX Visu die CometVisu auf HomeCockpit Minor. - Bitte keine PNs, Fragen gehören in das Forum, damit jeder was von den Antworten hat!

    Kommentar


      #17
      Die Datenrate auf dem KNX ist so langsam, dass klassisches Long Polling bei weitem nicht an die Grenze kommt.
      Mit schneller war nicht unbedingt gemeint "Die Daten kommen schneller vom Server zum Client" sondern schneller im Browser...

      => Lohnt es sich hier zu optimieren?
      LongPolling hatte bei mir schon funktioniert. Aber ich hatte das mit dem Echtzeit nicht nicht drin, weshalb ich da nun die Sache mit dem Index hätte führen müssen, was noch mehr komplizierten Code bedeutet hätte.

      Mit SSE ist die Implementierung einfacher und übersichtlicher geworden.

      Warum klassisches Long Polling verwendet wird ist auch ganz simpel erklärt:
      Nein, du muss nicht immer die Geschichtskeule auspacken. Weshalb LongPolling verwendet wurde ist mir seit längerem klar.

      D.h. hier eine weitere, optimierte Schnittstelle zu den Daten zu verwenden macht durchaus Sinn. Notwendig ist es aber nicht zwingend.
      Wenn der Code dadurch einfacher wird, der Client nicht immer ein Read rausschicken muss und wenn es dadurch nochmal einen kleinen Zacken schneller wird, dann macht es in der Tat sinn.
      Zwingend notwendig ist es nicht, nein.
      Ich halte es aber so wie mit IPv6... Das ist auch noch nicht notwendig. IPv4 geht ja noch ne Weile. Aber es ist durchaus lobenswert wenn man IPv6 jetzt schon beherrscht und somit up2date ist.

      aber zurück zum Thema:

      Jetzt fehlt noch der write-Request und dann kann ich erstmal anfangen meine CV Seite zu pflegen/aufzubauen... Danke an euch zwei für die Unterstützung. Die CV ist kurz davor meine Gira HS App abzulösen.

      Kommentar


        #18
        peuter
        Bin eben auf ein Problem gestoßen:
        Die LoginSession...

        Die wird beim Login vergeben und hat bei mir eine begrenzte Lebensdauer. Sie muss immer mal wieder erneuert werden.
        Mit dem Long-Polling war das kein Problem. Mit dem SSE ist das jetzt ein Problem.... Es gibt ja keinen regelmäßigen Request mehr vom Client. Demnach wird da auch keine Session am leben gehalten. Die läuft einfach aus. Aus die Maus.

        Wäre praktisch wenn man in CV irgendwie einstellen könnte dass er hin und wieder ein Lebenszeichen von sich gibt. Evtl. eine Keep-Alive-Protokollnachricht einführen? Oder einfach den Read-Befehl nochmal wiederholen um die Session zu erneuern.

        Hast du das in OH2 schon irgendwie gelöst?

        [update]

        Ich weiß nicht wie das in anderen HTTP-Server-Implementierungen ist, aber man könnte, statt auf das erneuern der Session zu warten, einfach die Socketverbindung als Indiz für eine Intakte Session verwenden. Bei meiner HTTP-Implementierung ist das nicht vorgesehen. Aber da die ganze Implementierung nur aus rund 2000 Zeilen Code besteht und ich für SSE eh "etwas tun musste", habe ich einfach den ganzen Code übernommen und modifiziert. Ich kann hier versuchen noch den Socket-Zustand zu überwachen. Ein pro-aktives Keep-Alive über das Protokoll wäre mir aber irgendwie lieber.
        Würde mich interessieren wie das im OH2 Umfeld gehandhabt wird.
        Zuletzt geändert von tuxedo; 09.10.2015, 07:56.

        Kommentar


          #19
          Ehrlich gesagt: keine Ahnung. Das Problem ist bei mit noch nicht aufgetreten. Macht aber auf Server seite keinen Sinn eine Session wegzuwerfen, wenn der Client noch verbunden ist. Das solltest Du auf Serverseite lösen und nicht durch den Client.

          Wenn ich mich recht erinnere verwendet openHAB2 an dieser Stelle auch Jersey: https://jersey.java.net/documentation/latest/sse.html und ich gehe mal davon aus, dass das Session handling dort passiert.
          Gruß
          Tobias

          Kommentar


            #20
            Macht aber auf Server seite keinen Sinn eine Session wegzuwerfen, wenn der Client noch verbunden ist.
            Natürlich macht das keinen Sinn. Deshalb war ja die Idee dass ich die persistente SSE SocketVerbindung überwache und mit deren Terminierung die Session ablaufen lasse.

            Das solltest Du auf Serverseite lösen und nicht durch den Client.
            Reden wir von der gleichen Session? Ich meine die Session die der Server dem Client in der Login-Antwort mit gibt. Die benutzt der Client dann beim Read. Damit weiß der Server, dass es einen gültigen Login gab. Und damit die Session nicht jeder mit dem Sessionstring daher kommen kann, ist diese auch noch an die Client-IP gebunden.

            Wenn der Client nun ein Login hinter sich hat und einen Read ausführt, dann wird ab diesem Zeitpunkt, dank SSE, nichts mehr vom Client zum Server gesendet. Woher soll der Server dann wissen ob der Client noch da ist? Da die Session nur begrenzt gültig ist (habs bis dato auf 2min stehen), läuft diese während dem SSE Read irgendwann ab.

            Einziges Indiz für einen Client der nicht mehr da ist (oder der den Browser geschlossen hat) ist aktuell die Socketverbindung.

            Aber so läuft erstmal die Session ab. Und wenn der Client dann irgendwann doch mal eine andere Seite aufruft und sich erneut für irgendwelche Adressen interessiert, dann verwendet er wieder seine Session, die aber dummerweise schon abgelaufen ist. Laut Protokolldefinition Antwortet der Server mit einen Fehlercode und leerer Antwort.
            Den Client scheint das aber nicht zu interessieren. Der tut einfach so als wäre nichts gewesen. Es ist kein neuer Login zu sehen welcher eine neue Session ergeben würde.

            Deshalb die Idee, dass der Client sich parallel zum verbundenen Read mit SSE, immer mal wieder sich beim Server meldet und sagt: Hey, ich bin noch da, und das ist die Session die ich gerade benutze. Sieh zu dass die nicht abläuft.

            Rein serverseitig lässt sich das nur implementieren, wenn man die Socketverbindung als Indiz her nimmt. Aber ich bezweifle dass man für andere Backends problemlos auf dieses Indiz zugreifen kann. Ich müsste meine HTTP Implementierung auch erst anpassen. Weil normalerweise interessiert die Socketverbindung nicht.

            Wenn ich mich recht erinnere verwendet openHAB2 an dieser Stelle auch Jersey: https://jersey.java.net/documentation/latest/sse.html und ich gehe mal davon aus, dass das Session handling dort passiert.
            Wie soll Jersey denn eine Session, die auf Protokollebene von CometVisu definiert/festgelegt ist automatisch behandeln? Du meinst die HTTP Session vielleicht? Aber das ist etwas anderes.

            Aktuell schau ich gerade ob ich mit dem HTML5 Worker-Konzept (das entspricht einem tatsächlichen nebenläufigen Thread) in regelmäßigen Abständen den Client sich beim Server melden lassen kann (und damit die Session am leben halte).

            Gruß
            Alex

            Kommentar


              #21
              Hab gerade nochmal einen Blick in den Quellcode geworfen, die Session den CV-Protokolls verwende ich garnicht in openHAB2 ich habe auch bei meinen vorherigen Posts immer an die HTTP-Session gedacht, hatte da garnicht mehr auf dem Schirm das es im CV-Protokoll nochmal eine eigene gibt. Beim alten openHAB1 Binding hab ich da die Atmosphere Session-ID benutzt.

              Ich glaube Du bist der erste, der diesen Teil des CometVisu-Protokoll so umsetzt, wie es definiert ist, denn auch das original Backend gibt beim Login das hier zurück:

              Code:
              #!/bin/sh
              echo Content-Type: text/plain
              echo
              
              echo "{ \"v\":\"0.0.1\", \"s\":\"SESSION\" }"
              Außer ich hab ne komplett veraltete Version, dann möge mich jemand bitte korrigieren. Also ist Backend-Seitig weder bei openHAB1/2 noch beim originalen Backend die Login Funktion implementiert und somit ist auch das Session-Handling auf dieser Protokollebene überflüssig.
              Von daher kann das gut sein, das der Client sich nicht korrekt verhält wenn die Session ausläuft, ganz einfach weil das bisher niemand genutzt hat.

              Rein vom Session-Handling würde ich die Gültigkeit der CometVisu-Session Backend-Seitig aber doch mit der HTTP-Session gleichsetzen. Da es im CometVisu-Protokoll kein Logout gibt, sehe ich da keinen Bedarf die CometVisu-Session vorher zu beenden. Kann aber sein dass ich hier was übersehe.

              Zumindest für die openHAB Backends dürfte es kein Problem sein, die Socketverbindung zu überwachen und die Session nicht zu beenden solange es der Client noch eine Verbindung zum Backend offen hat, aber genau wie das original Backend nutzen die ja das was im CV-Protokoll "anonymer Zugang" genannt wird. Also ist das aus meiner Sicht der Weg den ich gehen würde. Zusätzliche Keep-Alive Nachrichten erzeugen aus meiner Sicht nur unnötigen Traffic (auch wenns nicht viel ist). Oder für den zukünftigen "Universal-Client" das Keep-Alive Verhalten per Parameter an/-abschaltbar machen, wäre vermutlich die beste Option. Dann kann man das je nach Backend/Verbindungsart nutzen oder halt nicht.

              Vielleicht kann sich Chris M. als Urheber des Protokolls ja mal dazu äußern.
              Gruß
              Tobias

              Kommentar


                #22
                Das ist auch eine Möglichkeit: Die Session im Protokoll einfach ignorieren.
                Aber wozu gibt es eine Protokollspezifikation wenn man sich nicht dran hält?

                Hab das mit dem HTML5 Web Worker mal ausprobiert: Ist etwas stümperhaft gelöst (bin nicht ganz so fit in JavaScript), aber es scheint zu funktionieren: Man kann damit toll einen nebenläufigen Thread starten, der einen "KeepAlive" Request zum Server macht, xx Sekunden wartet, und sich dann wieder selbst aufruft um das ganze zu wiederholen.

                Alle 60 Sekunden einen Request machen der keine Antwort erfordert dürfte die Verbindung eigentlich nicht wirklich belasten. Müsste man nur sauber einbauen.

                Sich an die HTTP-Session zu hängen: Da muss ich nochmal schauen wie das andere HTTP Implementierungen machen. Zumindest bei meiner Implementierung hat hat im HTTP Session Objekt nur den Inputstream zur Verfügung. Hab für SSE jetzt schon den Outputstream dazu gebastelt. Die Streams an sich könnte man auch zurate ziehen. Aber wenn nix gesendet wird, weiß man nicht ob die Stream-Verbindung noch funktioniert. Ist also auch kein praktischer Indikator. Und SSE sieht es nicht vor dass der CLient sich darüber mehrfach beim Server meldet. SSE ist lediglich "1x zum Server, mehrfach vom Server zurück".

                Warten wir mal was Chris zu all dem sagt.

                Kommentar


                  #23
                  Zur CV Session:
                  Auch das "originale" Backend nutzt dort nur ein Dummy. Das ist durchaus erlaubt.
                  Hintergrund warum es das gibt ist, dass geplant ist (seit Anfang an, aber noch nie umgesetzt...) dass der Client Adressen als ein Filter abonieren kann. So muss nicht mehr der ganze String mit allen Adressen abgefragt werden sondern nur eine Filter-ID.
                  Auch hier ist die geplante Optimierung noch nie gekommen, da es nicht optimiert auch wunderbar funktioniert.

                  Hier kommt noch hinzu, dass das "originale" Backend fürchterlich dumm ist und keine Sessions kann, bzw. es sich keinen Status merken kann.

                  Eine erste Umsetzung hatte ich mir für GrAF vorgenommen. Und GrAF ist seit einem Jahr kurz davor aus dem Schatten zu treten und ein offizielles Projekt sein zu wollen...

                  Zum Web Worker:
                  Kann man machen, ist aber nicht klassisches JavaScript. JavaScript kennt keine blockierenden Aktionen - und die Ausnahmen die es gibt gelten als schlechter Stil. "Mutlithreading" läuft bei klassischem JavaScript dadurch dass man das Problem in kleine Teile zerhackt und die in der Event-Loop ausführen lässt (z.B. mit setIntervall). Daher sind Netz-Aktionen auch per Default asynchron.

                  Die WebWorker wurden später eingeführt um auch real mehrere Prozessoren nutzen zu können. Und wie gut und kompatibel die Browser-Unterstützung hier ist, weiß ich aktuell nicht genau. Was ich aber weiß, ist dass der Web Worker mit dem Haupt-JS-Programm wieder über die klassischen asynchronen Mechanismen kommuniziert. D.h. man kann die zur Netz-Kommunikation eigentlich auch direkt nutzen...

                  Zum Keep-Alive:
                  Der CV Client (also die Lib, die die Kommunikation im Browser übernimmt) hat jetzt schon einen Watchdog / Kepp-Alive-Timeout. Evtl. kann man das für diese Anwendung passend aufbohren.
                  TS2, B.IQ, DALI, WireGate für 1wire so wie Server für Logik und als KNX Visu die CometVisu auf HomeCockpit Minor. - Bitte keine PNs, Fragen gehören in das Forum, damit jeder was von den Antworten hat!

                  Kommentar


                    #24
                    Die Session weglassen, da optional... Wäre auch ein Ansatz. Aber dann ist ein Login auch unnötig.

                    Dank SSE sind auch die Filter irrelevant. Es wird ja nur 1x angefragt (bis zum nächsten Seitenwechsel).

                    Gut, kan könnte noch Seitenübergreifend die Filter nutzen um beim Wechseln von Seite A auf B und zurück auf A nicht erneut alle Adressen von A dem Server mitzuteilen, sondern die Filter zu benutzen.
                    Aber da hab ich noch keine Praxiserfahrung ob das was bringen würde, bzw. wieviele Adressen auf einer Seite zusammenkommen.
                    Dank der heute zur Verfügung stehenden Bandbreite ist das selbst (spätestens mit SSE) auch über eine Mobilfunkverbindung wohl nicht weiter kritisch.

                    GrAF?

                    Zum WebWorker:
                    Da blockiert nix. Das ist tatsächlich Multithreading für JavaScript, welches mit HTML5 kommt/kam.

                    In meinem Fall arbeitet die Event-Loop wie bisher. Nur dank SSE sendet sie nur einmal einen read-request, und bekommt, bis zum nächsten (anderen) read-request, solange Status-Updates geschickt, ohne dass erneut gefragt werden muss.
                    Im Nebenläufigen Thread wird dann quasi ein Keep-Alive der Session auf Protokollebene gefahren: Alle 60sek schickt der Client seine Session zum Server. Der weiß dann: Jepp, Client noch da, ich erneuere die Session für weitere XX Sekunden (idealerweise mehr als 60 sek, sonst ist es witzlos).



                    Bzgl. bereits existierendem WatchDog: Da müsste ich mal rein schauen wie man das mit einem Protokollebenen-KeepAlive zusammen passen könnte.

                    Kommentar


                      #25
                      Zitat von tuxedo Beitrag anzeigen
                      Die Session weglassen, da optional... Wäre auch ein Ansatz. Aber dann ist ein Login auch unnötig.

                      Dank SSE sind auch die Filter irrelevant. Es wird ja nur 1x angefragt (bis zum nächsten Seitenwechsel).

                      Gut, kan könnte noch Seitenübergreifend die Filter nutzen um beim Wechseln von Seite A auf B und zurück auf A nicht erneut alle Adressen von A dem Server mitzuteilen, sondern die Filter zu benutzen.
                      Aber da hab ich noch keine Praxiserfahrung ob das was bringen würde, bzw. wieviele Adressen auf einer Seite zusammenkommen.
                      Dank der heute zur Verfügung stehenden Bandbreite ist das selbst (spätestens mit SSE) auch über eine Mobilfunkverbindung wohl nicht weiter kritisch.
                      Die CV fragt sowieso alle Adressen ab, egal ob die auf der aktuellen Seite gebraucht werden oder nicht. Filter machen IMHO mit SSE überhaupt keinen Sinn.

                      Kommentar


                        #26
                        Zitat von jolt Beitrag anzeigen
                        Die CV fragt sowieso alle Adressen ab, egal ob die auf der aktuellen Seite gebraucht werden oder nicht.
                        Ich bin ja noch nicht so fit in Sachen CV, da mein CV Setup noch einer ein-seitigen Testumgebung gleicht. Aber wieso sollte die CV _alle_ Addressen _aller_ Seiten abfragen? Soweit ich das im Code gesehen hab, wird geschaut welche Seite gerade angezeigt wird, und nur die Adressen dieser Seite abgefragt. Wäre ja overkill immer alles abzufragen.

                        Werde das aber mal noch verifizieren.

                        Kommentar


                          #27
                          Ich halte das Verhalten für genau richtig. Normalerweise ändert sich auf dem Bus kaum etwas, es spricht also nichts dagegen einen Snapshot aller Zustände lokal im Client vorzuhalten. Das Umschalten zwischen Pages geht dann ohne weitere Kommunikation mit dem Backend.

                          Richtig übel ist dagegen dass RRD's und Images (mit refresh > 0) permanent neu geladen werden, auch wenn sie nicht sichtbar sind. Das muss noch gefixt werden. Steht auf meiner Todo Liste nach dem Feature Freeze ziemlich weit oben. Chris hat dazu auch schon Infrastruktur eingebaut, muss "nur" noch angeschlossen werden.

                          Kommentar


                            #28
                            Hast recht. Werden tatsächlich alle Adressen auf einmal gelesen, unabhängig von der betrachteten Seite.

                            Der Vorteil ist natürlich nicht von der Hand zu weisen. Hätte dabei nur angst gehabt dass das vllt. bei einem recht großen Setup etwas viel für den Client ist.

                            Kommentar


                              #29
                              Zitat von jolt Beitrag anzeigen
                              Richtig übel ist dagegen dass RRD's und Images (mit refresh > 0) permanent neu geladen werden, auch wenn sie nicht sichtbar sind. Das muss noch gefixt werden. Steht auf meiner Todo Liste nach dem Feature Freeze ziemlich weit oben. Chris hat dazu auch schon Infrastruktur eingebaut, muss "nur" noch angeschlossen werden.
                              das hört sich gut an. Denkst Du bitte dabei auch an mjepg? Ich wollte ein IP Cam Bild in die CV einblenden, das führt aber dazu das immer wenn die CV offen ist der MJPG Stream nonstop lädt/läuft, selbst wenn die Seite im Hintergrund ist.

                              danke,
                              Michael

                              Kommentar


                                #30
                                Zitat von MGK Beitrag anzeigen
                                das hört sich gut an. Denkst Du bitte dabei auch an mjepg? Ich wollte ein IP Cam Bild in die CV einblenden,
                                Das wäre super wenn das ginge. Selbiges hab ich auch vor.

                                Kommentar

                                Lädt...
                                X