Problem mit HttpUtils_NonblockingGet

Begonnen von DeeSPe, 24 Juni 2016, 20:58:26

Vorheriges Thema - Nächstes Thema

DeeSPe

Hallo Gemeinschaft,

ich habe Probleme mit der Integration von HttpUtils_NonblockingGet in mein Modul. Möchte diese Funktion gerne nutzen aber das scheint leider nicht möglich.

Der Server den ich abfrage erfordert zum einen dass kein Header mitgesendet wird und zum anderen muss zur einfachen Statusabfrage auch schon ein JSON String mitgesendet werden.
So wie ich den Code von HttpUtils.pm verstehe ist das so nicht möglich.
Einige Versuche einer Eigenimplementierung in die HttpUtils.pm sind bisher leider fehlgeschlagen.
Den Header habe ich schon wegbekommen, aber es scheitert beim syswrite anstelle von sysread denke ich.

Hat eventuell jemand einen Tipp für mich ohne dass ich die Funktionen selber in meinem Modul nachbauen muss?

Vielen Dank im Voraus.

Gruß
Dan
MAINTAINER: 22_HOMEMODE, 98_Hyperion, 98_FileLogConvert, 98_serviced

Als kleine Unterstützung für meine Programmierungen könnt ihr mir gerne einen Kaffee spendieren: https://buymeacoff.ee/DeeSPe

marvin78

Wenn man Tipps haben möchte UND selbst schon etwas probiert hat, ist es für den Helfer immer Hilfreich, wenn der Versuch hier gepostet wird (Beschreibung, Code etc.).

DeeSPe

#2
Hast Recht Marvin, das hätte ich wohl tun sollen!

Anbei ein diff um den Header komplett zu deaktivieren. Der Header muss dazu in den entsprechenden Params auf undef gesetzt werden.
my $param = {
    url         => $url,
    data        => $json,
    noshutdown  => 0,
    loglevel    => 3,
    header      => undef,
    hash        => $hash,
    callback    =>  \&My_ParseHttpResponse
};

HttpUtils_NonblockingGet( $param );


Ich ahne dass das Problem einer nun folgenden leeren Antwort daran liegt dass über die HttpUtils als erstes ein sysread ausgeführt wird. Der Server den ich abfrage erwartet aber ein syswrite als erstes und das bekomme ich irgendwie nicht rein in die HttpUtils.

Über Hilfe und Vorschläge bin ich sehr dankbar.

Gruß
Dan
MAINTAINER: 22_HOMEMODE, 98_Hyperion, 98_FileLogConvert, 98_serviced

Als kleine Unterstützung für meine Programmierungen könnt ihr mir gerne einen Kaffee spendieren: https://buymeacoff.ee/DeeSPe

DeeSPe

So gut ist meine Änderung an der HttpUtils.pm leider nicht. Habe gerade festgestellt dass damit das FHEM update und evtl. andere Sachen nicht funktionieren.

Ich werde wohl doch die Funktionalität der HttpUtils in meinem Modul nachahmen müssen.

Gruß
Dan
MAINTAINER: 22_HOMEMODE, 98_Hyperion, 98_FileLogConvert, 98_serviced

Als kleine Unterstützung für meine Programmierungen könnt ihr mir gerne einen Kaffee spendieren: https://buymeacoff.ee/DeeSPe

rudolfkoenig

HttpUtils ist in der aktuellen Form sehr flexibel, ich erweitere es aber gerne, wenn noch was fehlt.
Dazu brauche ich aber eine konkrete Teststellung.

Vmtl. reicht dir die neue Version von DevIo_OpenDev: wenn als device host:port, und ein viertes Parameter (CallbackFn) spezifiziert wird, dann wird das nicht blockierende HttpUtils_Connect aufgerufen.

Sonst: man sollte solche Fragen nicht in diesem Bereich stellen: erstens verwirrt es die Anfaenger, und zweitens lese ich (als HttpUtils Maintainer) sie nur zufaellig. Es gibt ja nicht umsonst die Datei MAINTAINER.txt

DeeSPe

Danke für die schnelle Antwort.

Ich hatte auch in die MAINTAINER.txt gesehen und versucht Dich direkt anzuschreiben Rudi. Das durfte ich aber nicht.
Beim Einordnen des Themas habe ich auch nach der richtigen Stelle im Forum gesucht, aber eine Stelle ala "Developer Anfängerfragen" habe ich nicht gefunden. Also gern verschieben wenn es einen besseren Ort gibt.

Vielen Dank für den Hinweis mit DevIo_OpenDev. Das sieht interessant aus und ich werde es damit mal probieren.

Ich gebe Bescheid ob es damit klappt.


Gruß
Dan
MAINTAINER: 22_HOMEMODE, 98_Hyperion, 98_FileLogConvert, 98_serviced

Als kleine Unterstützung für meine Programmierungen könnt ihr mir gerne einen Kaffee spendieren: https://buymeacoff.ee/DeeSPe

rudolfkoenig

ZitatIch hatte auch in die MAINTAINER.txt gesehen und versucht Dich direkt anzuschreiben Rudi.

Sehen reicht manchmal nicht, man muss auch lesen, verstehen, und passend handeln :)
ZitatThe third column specifies, where/how the maintainer should be contacted.

DeeSPe

Nachdem ich mich nun eine Weile nicht mehr damit beschäftigt hatte, möchte ich es nun noch einmal angehen mein Modul auf Nonblocking umzustellen.

Dem Rat von Rudi mir mal DevIo_OpenDev anzugucken bin ich nun gefolgt.
Leider sehe ich hier aber keine Möglichkeit (oder bin ich blind?) die JSON Daten mitzuliefern die zur Abfrage benötigt werden.

Nach meinem momentanen Verständnis (bin bei Weitem kein Profi) bleibt mir nur die Funktionen mit anderem Namen "nachzubauen" und auf meine Bedürfnisse anzupassen!?
Oder hat noch jemand einen anderen Tipp?

Vielen Dank im Voraus.

Gruß
Dan
MAINTAINER: 22_HOMEMODE, 98_Hyperion, 98_FileLogConvert, 98_serviced

Als kleine Unterstützung für meine Programmierungen könnt ihr mir gerne einen Kaffee spendieren: https://buymeacoff.ee/DeeSPe

rudolfkoenig

Kannst du mir bitte einen Testfall bauen?

DeeSPe

Zitat von: rudolfkoenig am 08 August 2016, 11:08:08
Kannst du mir bitte einen Testfall bauen?

Wie genau stellst Du Dir das vor?
Könnte Dir eine Anleitung geben wie man Hyperion in 3min installiert und ein Dummy Konfig-File zur Verfügung stellen, dann könntest Du selbst mit dem Server "spielen".

Im Moment mache ich den Aufruf im Modul so:
my $conn = IO::Socket::INET->new(PeerAddr=>"$host:$port",Timeout=>4);
syswrite $conn,"$data\n";
my $ret = <$conn>;


Zur einfachen get-Abfrage muss $data ein JSON ala {"command":"serverinfo"} ohne Header sein.

Würde das gerne durch "HttpUtils_NonblockingGet($params)" ersetzen wollen.

Danke im Voraus.

Gruß
Dan
MAINTAINER: 22_HOMEMODE, 98_Hyperion, 98_FileLogConvert, 98_serviced

Als kleine Unterstützung für meine Programmierungen könnt ihr mir gerne einen Kaffee spendieren: https://buymeacoff.ee/DeeSPe

rudolfkoenig

ZitatWie genau stellst Du Dir das vor?
Habe Schwierigkeiten das anders zu Formulieren. Ich brauche eine Beschreibung, anhand dessen ich dein Problem Nachstellen kann, moeglichst ohne gezwungen zu sein, irgendein Hardware kaufen zu muessen. Ok, muss wohl selbst socat Manual lesen, und hoffen, dass ich richtig rate.

Zitatmy $conn = IO::Socket::INET->new(PeerAddr=>"$host:$port",Timeout=>4);
syswrite $conn,"$data\n";
my $ret = <$conn>;

Klingt trivial. Hier ist ein mini Modul:
package main;
 
use strict;
use warnings;
use DevIo;
 
sub
d2_Initialize($)
{   
  my ($hash) = @_;
  $hash->{DefFn}  = "d2_Define";
  $hash->{ReadFn} = "d2_Read";
}     
     
sub   
d2_Define($$)
{         
  my ($hash, $def) = @_;
  my @a = split("[ \t][ \t]*", $def);
  $hash->{DeviceName} = $a[2];
  return DevIo_OpenDev($hash, 0, "d2_DoInit", sub($$$) {
    my ($h, $err) = @_;
    Log 1, $err ? "Error: $err" : "$a[2] connected";
  });
}

sub
d2_DoInit($)
{       
  my ($hash) = @_;
  DevIo_SimpleWrite($hash, '{"this_is":"JSON"}'."\n", 2);
}     
   
sub
d2_Read($)
{   
  my ($hash) = @_;
  my $buf = DevIo_SimpleRead($hash);
  Log 1, "R: got $buf";
}   
   
1; 


Zum Testen:
- im Terminal 1 "socat TCP-listen:1234 readline" starten
- im Terminal 2 FHEM mit "attr global logfile -" in fhem.cfg starten
- im Terminal 3 telnet zu FHEM, "define d d2 localhost:1234" eingeben. Im Terminal 1 erscheint ein JSON String.
- im Terminal 1 etwas tippen, erscheint im Terminal 2 (==FHEM) als Ausgabe.

justme1968

ich glaube dans problem ist das sein device an allen möglichen apezifikationen vorbei arbeitet und keinen http header will sondern nur einen json body. d.h. er möchte das non blocking handling ohne den header zu senden.

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

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

rudolfkoenig

Genau das ist mit DevIo_OpenDev einfach moeglich, siehe mein Beispiel.

DeeSPe

Zitat von: rudolfkoenig am 09 August 2016, 11:07:35
Habe Schwierigkeiten das anders zu Formulieren. Ich brauche eine Beschreibung, anhand dessen ich dein Problem Nachstellen kann, moeglichst ohne gezwungen zu sein, irgendein Hardware kaufen zu muessen. Ok, muss wohl selbst socat Manual lesen, und hoffen, dass ich richtig rate.

Klingt trivial. Hier ist ein mini Modul:
package main;
 
use strict;
use warnings;
use DevIo;
 
sub
d2_Initialize($)
{   
  my ($hash) = @_;
  $hash->{DefFn}  = "d2_Define";
  $hash->{ReadFn} = "d2_Read";
}     
     
sub   
d2_Define($$)
{         
  my ($hash, $def) = @_;
  my @a = split("[ \t][ \t]*", $def);
  $hash->{DeviceName} = $a[2];
  return DevIo_OpenDev($hash, 0, "d2_DoInit", sub($$$) {
    my ($h, $err) = @_;
    Log 1, $err ? "Error: $err" : "$a[2] connected";
  });
}

sub
d2_DoInit($)
{       
  my ($hash) = @_;
  DevIo_SimpleWrite($hash, '{"this_is":"JSON"}'."\n", 2);
}     
   
sub
d2_Read($)
{   
  my ($hash) = @_;
  my $buf = DevIo_SimpleRead($hash);
  Log 1, "R: got $buf";
}   
   
1; 


Zum Testen:
- im Terminal 1 "socat TCP-listen:1234 readline" starten
- im Terminal 2 FHEM mit "attr global logfile -" in fhem.cfg starten
- im Terminal 3 telnet zu FHEM, "define d d2 localhost:1234" eingeben. Im Terminal 1 erscheint ein JSON String.
- im Terminal 1 etwas tippen, erscheint im Terminal 2 (==FHEM) als Ausgabe.

Hallo Rudi und danke für Deinen ersten Hilfeversuch.
Ich habe es nun mehrfach gelesen und versucht zu verstehen, aber ich begreife nicht so richtig was das ist und wie ich damit mein Problem lösen kann.

Zitat von: justme1968 am 09 August 2016, 11:10:40
ich glaube dans problem ist das sein device an allen möglichen apezifikationen vorbei arbeitet und keinen http header will sondern nur einen json body. d.h. er möchte das non blocking handling ohne den header zu senden.

Andre hat vollkommen richtig verstanden.
Ich möchte keinen großen Aufriss machen, einfach nur ohne Header JSON bei Erstkommunikation senden. Hatte gedacht das wäre ohne größere Umstände möglich in die HttpUtils mit einzubauen, eventuell benötigt das ja noch jemand in Zukunft für andere Module.

Wie gesagt, eine Anschaffung von Hardware wäre nicht nötig zum Testen. Eine Testumgebung ist in 5 min aufgesetzt.
Einfach wie hier beschrieben mit dem HyperCon Tool den Hyperion Server installieren.
Eine Dummy Konfig Datei (bei der keinerlei Hardware benötigt ist) kann ich zur Verfügung stellen.

Gruß
Dan

P.S. Ich schaue mir diese DevIo Geschichte nochmal genauer an, vielleicht war ich eben auch nicht so richtig auffassungsfähig.
MAINTAINER: 22_HOMEMODE, 98_Hyperion, 98_FileLogConvert, 98_serviced

Als kleine Unterstützung für meine Programmierungen könnt ihr mir gerne einen Kaffee spendieren: https://buymeacoff.ee/DeeSPe

justme1968

schau dir rudis beispiel noch mal an. es macht genau das was du möchtest. die verbindung wird aufgebaut, sobald sie steht wird ein fallback aufgerufen und du kannst schreiben, sobald eine antwort kommt wird deine lese routine aufgerufen. der einzige ungerschied zum nonblocking get ist das du die antwort eventuell selber zusammenbauen musst wenn mehr daten kommen als in ein read passt und das du die verbindung selber zu machen musst.
hue, tradfri, alexa-fhem, homebridge-fhem, LightScene, readingsGroup, ...

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