Frage zu TcpServerUtils und Einbindung in ReadFn

Begonnen von DS_Starter, 16 September 2018, 07:47:30

Vorheriges Thema - Nächstes Thema

DS_Starter

Guten Morgen,

ich bin gerade dabei das erste mal TcpServerUtils einzusetzen um einen TCP-Server aufzubauen und brauche mal etwas Hilfe bei der Verwendung.
Ich habe in anderen Modulen, die TcpServerUtils einsetzen in der ReadFn immer ein ähnliches Konstrukt gefunden. Hier das Beispiel aus MQTT2_SERVER_Read:


  my ($hash, $reread) = @_;

  if($hash->{SERVERSOCKET}) {   # Accept and create a child
    my $nhash = TcpServer_Accept($hash, "Log2Syslog");
    return if(!$nhash);
    $nhash->{CD}->blocking(0);
    readingsSingleUpdate($hash, "nrclients",
                         ReadingsVal($hash->{NAME}, "nrclients", 0)+1, 1);
    return;
  }

  my $sname = $hash->{SNAME};
  my $cname = $hash->{NAME};
  my $c = $hash->{CD};
  ........


Meine zwei grundsätzliche Verständnisprobleme sind:

1. Wenn in der ReadFn immer in den  if($hash->{SERVERSOCKET})-Zweig abgebogen wird (mit einem return darin), wie werden dann jemals Daten durch den darunter liegenden Code gelesen, da ja $hash->{SERVERSOCKET} immer existiert solange der Server offen ist ?
2. TcpServer_Accept liefert ja eine Hashreferenz zurück ($nhash) die "{CD}" enthält. Im Code unter der If-Bedingung wird "my $c = $hash->{CD}" verwendet. Ich habe aber bisher nirgendwo eine Stelle gefunden wo aus $nhash->{CD} $hash->{CD} wird.

Ich habe es bis jetzt zwar hinbekommen Daten mit dem Server zu empfangen, aber nur wenn ich ein solches Konstrukt in der ReadFn verwende:


if($hash->{SERVERSOCKET}) {   # Accept and create a child
   my $nhash = TcpServer_Accept($hash, "Log2Syslog");
   return if(!$nhash);
   $nhash->{CD}->blocking(0);
   my $client = $nhash->{NAME};
   $hash->{TCPPADDR} = (split '_', $client)[-2];
   my $c = $nhash->{CD};
   my $ret = sysread($c, $data, 1024);  # returns undef on error, 0 at end of file and Integer, number of bytes read on success.
   .....         


D.h. es klappt wenn ich das Datenlesen innerhalb des if($hash->{SERVERSOCKET})-Zweiges mache unter Verwendung von  $nhash->{CD}.

Irgendetwas übersehe ich was mich daran hindert TcpServerUtils so einzusetzen wie es andere Module vormachen.
Für ein paar Erläuterungen wäre ich euch sehr dankbar.

LG und einen schönen Sonntag,
Heiko
ESXi@NUC+Debian+MariaDB, PV: SMA, Victron MPII+Pylontech+CerboGX
Maintainer: SSCam, SSChatBot, SSCal, SSFile, DbLog/DbRep, Log2Syslog, SolarForecast,Watches, Dashboard, PylonLowVoltage
Kaffeekasse: https://www.paypal.me/HMaaz
Contrib: https://svn.fhem.de/trac/browser/trunk/fhem/contrib/DS_Starter

CoolTux


    if( $hash->{SERVERSOCKET} ) {               # Accept and create a child
        TcpServer_Accept( $hash, $hash->{'NAME'} );
        return;
    }

    # Read 1024 byte of data
    my $buf;
    my $ret = sysread($hash->{CD}, $buf, 2048);


    # When there is an error in connection return
    if( !defined($ret ) or $ret <= 0 ) {
        CommandDelete( undef, $name );
        Log3 $name, 5, " ($name) - Connection closed for $name";
        return;
    }

    ...


Bei mir geht es so ohne Probleme. Das Lesen erfolgt also außerhalb der Bedingung. Ganz zum Schluss wird dann $buf an eine bearbeitende Funktion weiter gegeben.
Du musst nicht wissen wie es geht! Du musst nur wissen wo es steht, wie es geht.
Support me to buy new test hardware for development: https://www.paypal.com/paypalme/MOldenburg
My FHEM Git: https://git.cooltux.net/FHEM/
Das TuxNet Wiki:
https://www.cooltux.net

DS_Starter

Morgen Leon,

ZitatBei mir geht es so ohne Probleme....

Ja, ich weiß  :) Habe auch im AMAD-Modul nachgeschaut.
Kann nur nicht erkennen _wie_ bzw. warum es so z.B. auch bei dir funktioniert. Das ist ja gerade mein Hirnknoten....
ESXi@NUC+Debian+MariaDB, PV: SMA, Victron MPII+Pylontech+CerboGX
Maintainer: SSCam, SSChatBot, SSCal, SSFile, DbLog/DbRep, Log2Syslog, SolarForecast,Watches, Dashboard, PylonLowVoltage
Kaffeekasse: https://www.paypal.me/HMaaz
Contrib: https://svn.fhem.de/trac/browser/trunk/fhem/contrib/DS_Starter

CoolTux

Guten Morgen Heiko,

Eventuell liegt es am Open. So tief stecke ich da auch nicht drin. Damals hat mir Andre geholfen, ist schon ne ganze Weile her.
Zeig mal bitte Deine Open.
Du musst nicht wissen wie es geht! Du musst nur wissen wo es steht, wie es geht.
Support me to buy new test hardware for development: https://www.paypal.com/paypalme/MOldenburg
My FHEM Git: https://git.cooltux.net/FHEM/
Das TuxNet Wiki:
https://www.cooltux.net

DS_Starter

#4
Open ist ganz unspektakulär.


      $lh = "global" if(!$lh);
      my $ret = TcpServer_Open($hash,$port,$lh);
      if($ret) {       
          $err = "Can't open Syslog TCP Collector at $port: $ret";
          Log3 ($hash, 1, "Log2Syslog $name - $err");
          readingsSingleUpdate ($hash, 'state', $err, 1);
          return;
      }
ESXi@NUC+Debian+MariaDB, PV: SMA, Victron MPII+Pylontech+CerboGX
Maintainer: SSCam, SSChatBot, SSCal, SSFile, DbLog/DbRep, Log2Syslog, SolarForecast,Watches, Dashboard, PylonLowVoltage
Kaffeekasse: https://www.paypal.me/HMaaz
Contrib: https://svn.fhem.de/trac/browser/trunk/fhem/contrib/DS_Starter

rudolfkoenig

ZitatWenn in der ReadFn immer in den  if($hash->{SERVERSOCKET})-Zweig abgebogen wird (mit einem return darin), wie werden dann jemals Daten durch den darunter liegenden Code gelesen, da ja $hash->{SERVERSOCKET} immer existiert solange der Server offen ist ?
Die einzige Aufgabe der Instanz mit SERVERSOCKET ist TcpServer_Accept durchzufuehren (und evtl. noch Statistiken). Durch den Accept wird eine weitere Instanz des gleichen Typs angelegt die eine Verbindung repraesentiert und im ReadFn die eigentliche Arbeit macht:
- ohne SERVERSOCKET dafuer mit CD/FD, PEER und PORT. CD/FD enthaelt den neuen Filedeskriptor.
- mit TEMPORARY (damit es nicht gespeichert wird)
- SNAME verweist auf die "richtige" Instanz, damit man die Attribute abfragen kann.

ZitatIch habe aber bisher nirgendwo eine Stelle gefunden wo aus $nhash->{CD} $hash->{CD} wird.
Passiert indirekt: TcpServer_Accept traegt den neuen Filedeskriptor in die globale %selectlist ein, damit wird ReadFn von fhem.pl/select mit dem temporaeren Instanzhash aufgerufen, wenn Daten genau bei dieser Verbindung anstehen.

Siehe auch "list TYPE=FHEMWEB", bzw. "man -s2 accept",

CoolTux

Guten Morgen Rudi,

Vielen Dank für die gute Erklärung. Dann muss Heiko seine Funktion also auf jeden Fall auch außerhalb der Bedingung weiter funktionieren.


Grüße
Du musst nicht wissen wie es geht! Du musst nur wissen wo es steht, wie es geht.
Support me to buy new test hardware for development: https://www.paypal.com/paypalme/MOldenburg
My FHEM Git: https://git.cooltux.net/FHEM/
Das TuxNet Wiki:
https://www.cooltux.net

DS_Starter

Morgen Rudi,

danke für die Erläuterung der Zusammenhänge. Wie Cooltux schon schrieb, müsste es ja auch wie bei euch auch funktionieren.
Ich versuche es jetzt mit den neuen Erkenntnissen nochmal.
ESXi@NUC+Debian+MariaDB, PV: SMA, Victron MPII+Pylontech+CerboGX
Maintainer: SSCam, SSChatBot, SSCal, SSFile, DbLog/DbRep, Log2Syslog, SolarForecast,Watches, Dashboard, PylonLowVoltage
Kaffeekasse: https://www.paypal.me/HMaaz
Contrib: https://svn.fhem.de/trac/browser/trunk/fhem/contrib/DS_Starter

CoolTux

Versuch es mal in einem minimalistischen Modul. Nur die TcpServer Geschichten einbauen. Habe ich auch gemacht, aber nur um ein Netzwerkgeräte zu emulieren bei der Entwicklung eines Modules.
Du musst nicht wissen wie es geht! Du musst nur wissen wo es steht, wie es geht.
Support me to buy new test hardware for development: https://www.paypal.com/paypalme/MOldenburg
My FHEM Git: https://git.cooltux.net/FHEM/
Das TuxNet Wiki:
https://www.cooltux.net

DS_Starter

Wollte nur noch mal kurz Rückmeldung geben, dass der TCP-Server nun so läuft wie ich es erwartet habe. Dank der Info von Rudi bezüglich der Zusammenhänge konnte ich eine Reihe von Fehlern beseitigen die sich vor allem aus dem Switchen des Hash-Kontexts bei dieser Verwendung ergeben haben.
Jetzt gehts an die Feinheiten mit den vllt. nächsten Hürden  ;)

Vielen Dank euch !

LG,
Heiko
ESXi@NUC+Debian+MariaDB, PV: SMA, Victron MPII+Pylontech+CerboGX
Maintainer: SSCam, SSChatBot, SSCal, SSFile, DbLog/DbRep, Log2Syslog, SolarForecast,Watches, Dashboard, PylonLowVoltage
Kaffeekasse: https://www.paypal.me/HMaaz
Contrib: https://svn.fhem.de/trac/browser/trunk/fhem/contrib/DS_Starter