Vorschlag: EventSource support für HttpUtils

Begonnen von justme1968, 14 Juli 2021, 20:33:01

Vorheriges Thema - Nächstes Thema

justme1968

hallo rudi,

ich bin gerade dabei event support in das HUEBridge modul einzubauen. wie es ausschaut hat philips bzw. signify sich dafür das EventSource protokoll ausgesucht. das ist älter als websockets und basiert auf chunked. der knackpunkt für das hue modul ist das dabei nicht wie bei der aktuellen chunked implementierung gewartet wird bis alles komplett ist, sondern der callback für jeden chunk aufgerufen werden müsste.

der folgende patch tut genau das. da es an einem auf text/event-stream gesetzen accept header (und das auch nur im nonblocking fall) erkannt wird sollte das ganze völlig rückwärts kompatibel sein.

Index: HttpUtils.pm
===================================================================
--- HttpUtils.pm (revision 24746)
+++ HttpUtils.pm (working copy)
@@ -621,6 +621,8 @@
   $s = 0 if($hash->{protocol} eq "https");

   if($hash->{callback}) { # Nonblocking read
+    $hash->{EventSource} = 1 if($hdr =~ m/Accept:\s*text\/event-stream/i);
+
     $hash->{FD} = $hash->{conn}->fileno();
     $hash->{buf} = "";
     delete($hash->{httpdatalen});
@@ -729,7 +731,16 @@
         return 1;
       }
       return 0 if(length($r) < $l);
-      $hash->{httpdata} .= substr($r, 0, $l);
+
+      my $ret = substr($r, 0, $l);
+      if( $hash->{EventSource} ) {
+        $hash->{callback}($hash, undef, $ret);
+
+      } else {
+        $hash->{httpdata} .= $ret;
+
+      }
+
       $hash->{buf} = substr($r, $l);
     }
     return 0;
hue, tradfri, alexa-fhem, homebridge-fhem, LightScene, readingsGroup, ...

https://github.com/sponsors/justme-1968

rudolfkoenig

Danke, habs nach einem kurzen Test unveraendert eingecheckt.

justme1968

hue, tradfri, alexa-fhem, homebridge-fhem, LightScene, readingsGroup, ...

https://github.com/sponsors/justme-1968

justme1968

bei sehr langen events kann es passieren das die daten in mehrere kleineren häpchen ankommen. mit folgendem patch werden diese erst zusammengesetzt und der callback erst aufgerufen wenn das event komplett ist:

Index: HttpUtils.pm
===================================================================
--- HttpUtils.pm (revision 25477)
+++ HttpUtils.pm (working copy)
@@ -734,7 +734,13 @@

       my $ret = substr($r, 0, $l);
       if( $hash->{EventSource} ) {
-        $hash->{callback}($hash, undef, $ret);
+        $hash->{httpdata} .= $ret;
+        if( $ret !~ /\n$/ ) {
+          # data is incomplete
+        } else {
+          $hash->{callback}($hash, undef, $hash->{httpdata});
+          $hash->{httpdata} = '';
+        }

       } else {
         $hash->{httpdata} .= $ret;


erfolgreich getestet mit bis zu dreiteiligen (4096+4096+2089 bytes) events einer aktuellen hue bridge.
hue, tradfri, alexa-fhem, homebridge-fhem, LightScene, readingsGroup, ...

https://github.com/sponsors/justme-1968

rudolfkoenig