Timeout bei HttpUtils_NonblockingGet

Begonnen von maluk, 19 Oktober 2020, 21:44:07

Vorheriges Thema - Nächstes Thema

maluk

Ich muss mein Arlo-Modul gerade um 2-Faktor-Authentifizierung erweitern. Dabei müssen mehrere REST-Aufrufe hintereinander erfolgen, was ich mit HttpUtils_NonblockingGet mache. Die Kette der REST-Aufrufe läuft leider fast nie durch, weil immer irgendwann ein Timeout auftritt. Es liegt aber nciht daran, dass der Server nicht antwortet, sondern dass FHEM den Callback nicht aufruft.

Ich habe einige eigene Log-Punkte in HttpUtils eingebaut: in Zeile 631 bei directReadFn logge ich die Länge des empfangenen Buffer. Bei erfolgreichen Aufrufen kommt hier am Ende immer eine Buffer-Länge von 0, bei den Timeouts aber immer die Länge des empfangenen Chunks. Die Prüfung von HttpUtils_DataComplete schlägt hier nicht an, da der Arlo-Server keine Content-Length liefert.

In HttpUtils_Err habe ich in Zeile 109 folgende Anweisung ergänzt:
  my ($err, $ret, $redirect) = HttpUtils_ParseAnswer($hash);

$ret übergebe ich dann im Callback mit, damit ich auch im Fehlerfall sehe, welcher Body empfangen wurde - und es kommt tatsächlich immer die volle Nachricht mit.

Offensichtlich wird die directReadFn nicht mehr aufgerufen, wenn der Server nichts mehr sendet. Hat jemand eine Idee, woran das liegen kann? Ich hatte schon zuvor immer wieder Timeouts im Logfile gesehen, aber durch meinen aktuellen Umbau ist das Problem zum Showstopper geworden.

maluk

Ich habe meine REST-Aufrufe etwas umgeschrieben: ich verwende jetzt keepalive und habe das Lesen der Ergebnisse vom Server selbst implementiert. Eine (dem BlockingGet sehr ähnliche) Read-Methode wird solange über den InternalTimer aufgerufen, bis alle Daten gelesen wurden oder ein Timeout auftritt. Der Hauptunterschied zu BlockingGet ist, dass wieder der Timer aufgerufen wird, falls aktuell keine Daten mehr aus der Verbindung kommen. Das scheint zu funktionieren und blockiert auch FHEM nicht. Trotzdem sehr seltsam, dass der normale NonblockingGet nicht funktioniert.

rudolfkoenig

Woran sollte HttpUtils_DataComplete erkennen, dass alle Daten da sind?

maluk

Eine einfache Option wäre, beim Timeout in HttpUtils_Err HttpUtils_ParseAnswer aufzurufen und das Ergebnis in den Calback zu übergeben. Wenn ich einen REST-Aufruf mache und beim Timeout ein valides JSON übergeben bekomme, kann ich mit der Verarbeitung fortsetzen.

Ich werde das Ganze noch weiter untersuchen und hier die Ergebnisse posten.

rudolfkoenig

Ich finde es immer noch befremdlich, dass die Gegenseite einem nicht mitteilt, wann die Daten vollstaendig sind.

Bin bereit ParseAnswer im Fehlerfall optional aufzurufen, brauche aber irgendeinen Server, mit dem ich das testen kann. Uebrigens kann man den Aufruf, soweit ich es ohne testen beurteilen kann, selbst im callback durchfuehren.