Autor Beitrag
Stephan.Woebbeking
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 97



BeitragVerfasst: Do 12.07.12 16:47 
Hallo, ich arbeite mit der TIdHTTP Komponente um Daten auszutauschen. Die serverseitige Protokollbeschreibung lautet (gekürzt, Entwicklungsinformationen) wie folgt:

ausblenden Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
[...]
The connection is kept open until the update procedure is finished; there’s no need to poll.
The [...] sends one line of output at each time that it is able to re-calculate the remaining work with good confidence (there’s no guarantee for a maximum time period or percentage granularity when the progress estimation is updated).
[...]
> GET /software/update/123456789abcdef/progress HTTP/1.1
>
< HTTP/1.1 200 OK
< Content-Type: text/plain; charset=UTF-8
<
< 134.0
< 130.5
< 127.0
... time passes ...
< 9.0
< 3.0
< 0.0
<

Note that [...] doesn’t send a Content-Length header for the streaming response. The response is complete when the [...] drops the connection.


Dabei bedeutet ">" vom Client zum Server und "<" vom Server zum Client. Nun bekomme ich zwei solcher Pakete mit dem zeitlichen Abstand von ca. 5,5 Sekunden. Die Information aus dem ersten Paket wird angezeigt, die aus dem zweiten nicht. Die HTTP Verbindung baue ich folgendermaßen auf:

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
            try
              httpMonitorConnector.ReadTimeout := 200;
              httpMonitorConnector.ConnectTimeout := 0;
              httpMonitorConnector.Response.KeepAlive := True;
              httpMonitorConnector.Get( '/software/update/' + Connector.ip + ' ' + location + 'progress' );
            except on E: EIdReadTimeout do begin
              MemoLogger.AddToLog( 'Exception as expected: ' + E.ClassName + ' ' + E.Message );
            endend;


Die Abfrage die ich durch einen Timer durchführe sieht so aus:

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
  a := -1;
  if Assigned( httpMonitorConnector.IOHandler ) then begin
    httpMonitorConnector.IOHandler.CheckForDataOnSource( 5 );
    a := httpMonitorConnector.IOHandler.InputBuffer.Size;
    if ( httpMonitorConnector.IOHandler.InputBuffer.Size > 0 ) then
      MemoLogger.AddToLog( httpMonitorConnector.IOHandler.ReadLn );
  end;
  logger.Debug( '< Monitor Timer ticked: Assigned: ' + BoolToStr( Assigned( httpMonitorConnector.IOHandler ), True ) + ' Size: ' + IntToStr( a ) );


Jetzt weiß ich einfach nicht, warum das erste Paket korrekt angenommen wird, das zweite jedoch nicht? Weitere Pakete kommen dann auch nicht, aber ich denke das Problem liegt eher serverseitig. Wäre es evt. möglich, dass die TCP Verbindung abgebaut wird? Aus Gründen die mir bisher nicht bekannt sind? Falls jemand eine Idee hat, immer her damit!

Danke,
Stephan
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19285
Erhaltene Danke: 1743

W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: Do 12.07.12 17:02 
user profile iconStephan.Woebbeking hat folgendes geschrieben Zum zitierten Posting springen:
Wäre es evt. möglich, dass die TCP Verbindung abgebaut wird? Aus Gründen die mir bisher nicht bekannt sind?
Naja, wo hast du denn eine offen? Ich sehe nichts davon.
Du machst eine Abfrage auf dem Server mit Get, mehr nicht, sprich verbinden, Seite abrufen, Verbindung schließen. Das ist bei HTTP so gedacht.

Wenn du eine TCP-Verbindung offen halten willst, dann musst du auch einen expliziten TCP-Client benutzen. Ich glaube nicht, dass du da mit TIdHttp weiterkommst...
Martok
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 3661
Erhaltene Danke: 604

Win 8.1, Win 10 x64
Pascal: Lazarus Snapshot, Delphi 7,2007; PHP, JS: WebStorm
BeitragVerfasst: Do 12.07.12 20:17 
Das ist Comet, ich bin mir relativ sicher dass das mit Indy nicht unfallfrei geht. Wir hatten letztes Jahr im AGS bei der Brett-KI eigentlich Long Polling vorgesehen, das hab ich jedenfalls nicht stabil bekommen. Und das ist noch einfach, weil's nur ein normaler Request ist, der halt länger dauert. Mindestens muss der Request in einem Thread passieren, da Get() den Thread blockiert und damit dein Timer gar nicht tickt (nur einmal, ganz am Ende).

Was mit der Connection passiert, findest du wohl am einfachsten mit Wireshark raus. Falls einer die Verbindung abbricht, sieht man das ja spätestens auf TCP-Ebene.

_________________
"The phoenix's price isn't inevitable. It's not part of some deep balance built into the universe. It's just the parts of the game where you haven't figured out yet how to cheat."
Stephan.Woebbeking Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 97



BeitragVerfasst: Mo 16.07.12 17:56 
Ok, dann habe ich jetzt mal den Verbindungsaufbau so umgeändert:

ausblenden Delphi-Quelltext
1:
2:
3:
4:
            TcpClient1.RemoteHost := Connector.ip;
            TcpClient1.RemotePort := '80';
            TcpClient1.Connect;
            TcpClient1.Sendln( 'GET ' + location + 'progress HTTP/1.1' );


Und die Nutzung der Verbindung (Timer) dann so:

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
  ret := TcpClient1.WaitForData( 5 );
  if ( ret ) then begin
    line := TcpClient1.Receiveln;
    MemoLogger.AddToLog( line );
  end;


Ich bekomme aber über diese Verbindung GAR KEINE Daten. Obwohl sie im Netzwerk (Wireshark) übertragen werden. Wende ich die Komponente falsch an? Die Ausführung über den Timer erfolgt, das habe ich anhand eines Breakpoints überprüft. Allerdings liefert WaitForData() nie True zurück, obwohl ich hier eine Signalisierung erwarten würde, sobald Daten anstehen. So gesehen ist das aber noch schlimmer als die ursprüngliche Lösung. Bei der habe ich übrigens herausgefunden, dass dort in einem Paket das FIN Flag gesetzt und das nächste kommende Packet mittels RST, ACK abgewehrt wird. Woran kann das liegen? Kann ich das unterbinden?

Stephan
Stephan.Woebbeking Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 97



BeitragVerfasst: Fr 20.07.12 09:15 
Niemand eine Idee dazu???