6. Kleine Denkpause gefällig? / in need of a reflection period?
Nachdem nun die Übertragung an den Webservice initiiert wurde bleibt uns als nächstes nur eines: Warten...
Das hört sich schlimmer an als es tatsächlich ist. Rufen wir uns an dieser Stelle mal das uralte Grundprinzip der EDV ins Gedächtnis zurück: EVA
E ingabe
V erarbeitung
A usgabe
Als Entwickler haben wir uns dieses Prinzip vermutlich schon so verinnerlicht, dass wir es gar nicht mehr bewusst zur Kenntnis nehmen 😊.
Unser oXmlHttp.Send() ist die Eingabe die der Server entgegen nimmt.
In dem Augenblick in dem die Daten beim Zielserver ankommen beginnt dort die Verarbeitung. Diese kennt jedoch verschiedene Stufen.
Wie der aktuelle Stand der Dinge beim Server aussieht, darüber gibt uns die oXmlHttp.Status Eigenschaft Auskunft. Sie liefert uns alle möglichen Werte darüber, was bei der Verarbeitung so alles passiert ist. Aber ungeachtet der vielen verschiedenen Werte interessiert uns für die weitere Verarbeitung bzw. für den Empfang der Daten nur ein einziger Status.
Sobald wir den Wert 200 geliefert bekommen bedeutet dies, dass der Webservice Daten zur Ausgabe bereithält. Alle anderen Statuswerte ermöglichen uns eine gezielte Reaktion auf Probleme, die bei der Kommunikation zum und vom Server auftreten könnten.
Auf dieser Seite findet Ihr eine umfangreiche Liste der möglichen Werte:
https://docs.microsoft.com/en-us/previous-versions/windows/desktop/ms767625(v%3Dvs.85)
Wie bereits geschrieben bedeutet der Status 200 dass die Verarbeitung erfolgreich abgeschlossen wurde und nun das Ergebnis abgerufen werden kann.
Uns interessiert jedoch nicht, was der Service gerade so anstellt. Uns interessiert nur, ob unsere Anfrage angekommen ist, ob sie zur Verarbeitung angenommen wurde, ob die Verarbeitung noch läuft und ob die Verarbeitung abgeschlossen ist. Beim letzten Punkt steht dann auch hoffentlich ein Status 200 bereit.
Hierbei müssen wir uns darüber im klaren sein, dass eine abgeschlossene Verarbeitung nicht automatisch auch eine erfolgreiche Verarbeitung bedeutet.
Zunächst benötigen wir also eine kleine Schleife die immer wieder beim Service anfragt ob er mit der Verarbeitung fertig ist. Für diese Schleife greifen wir auf eine andere Eigenschaft des oXmlHttp-Objektes zu, den oXmlHttp.ReadyState. Diese Eigenschaft reduziert sich auf den eigentlichen Stand der Verarbeitung nach dem EVA Prinzip.
- Wurde eine Verbindung zum Server hergestellt
- wurden die Daten erfolgreich an den Webservice übermittelt
- werden die übermittelten Daten verarbeitet
- ist die Verarbeitung abgeschlossen und kann die Antwort abgerufen werden.
https://docs.microsoft.com/en-us/previous-versions/windows/desktop/ms761388(v%3dvs.85)
Wird der letzte dieser vier Punkte gemeldet, dann ist es Zeit in Erfahrung zu bringen, ob bei der Verarbeitung alles glatt gelaufen ist und wir tatsächlich Daten abrufen können.
In der Praxis sieht es also so aus, dass wir in einer Schleife den .ReadyState = 4 prüfen und anschließend den .Status = 200 und erst wenn beide Eigenschaften uns sozusagen ihr GO gegeben haben, dann können wir auch wirklich Daten vom Webservice abrufen.
DECLARE Sleep IN Win32API INTEGER nMilliseconds
DO WHILE .T.
DO CASE
CASE oXmlHttp.ReadyState = 0
=myFormObj.StatusOutput( [(0) request not initialized] )
CASE oXmlHttp.ReadyState = 1
=myFormObj.StatusOutput( [(1) server connection established] )
CASE oXmlHttp.ReadyState = 2
=myFormObj.StatusOutput( [(2) request received] )
CASE oXmlHttp.ReadyState = 3
=myFormObj.StatusOutput( [(3) processing request] )
CASE oXmlHttp.ReadyState = 4
=myFormObj.StatusOutput( [(4) request finished and response is ready] )
EXIT
ENDCASE
=sleep(200)
ENDDO
CLEAR DLLS [Sleep]
IF oXmlHttp.status != 200
*// Something went wrong, so this is the time to call a routine
*// that visualizes the state from oXmlHttp.status
=GiveFeedback( oXmlHttp.status )
ELSE
*// everything went fine, so we can read the data
ENDIF
Bekommen wir den Status 200 gemeldet, dann beginnt der nächste Schritt, andernfalls sollten ein paar Informationen bzgl. der aufgetretenen Probleme ausgegeben werden.
Hierbei sind nicht alle Statuswerte zwingend auf Fehler zurückzuführen und müssen somit auch nicht explizit innerhalb der Feedbackroutine verarbeitet werden.
FUNCTION GiveFeedback as Boolean
LPARAMETERS vStatus as Integer
DO CASE
CASE m.vStatus = 100
lcInfo = [Continue]
CASE m.vStatus = 101
lcInfo = [Switching protocols]
* // #######################################################
* // this Block (201/202/203/204/205/206) might not be part
* // of the error handling and could be used for further
* // Web Service handling because of non-default data
CASE m.vStatus = 201
lcInfo = [Created]
CASE m.vStatus = 202
lcInfo = [Accepted]
CASE m.vStatus = 203
lcInfo = [Non-Authoritative Information]
CASE m.vStatus = 204
lcInfo = [No Content]
CASE m.vStatus = 205
lcInfo = [Reset Content]
CASE m.vStatus = 206
lcInfo = [Partial Content]
* // #######################################################
CASE m.vStatus = 300
lcInfo = [Multiple Choices]
CASE m.vStatus = 301
lcInfo = [Moved Permanently]
CASE m.vStatus = 302
lcInfo = [Found]
CASE m.vStatus = 303
lcInfo = [See Other]
CASE m.vStatus = 304
lcInfo = [Not Modified]
CASE m.vStatus = 305
lcInfo = [Use Proxy]
CASE m.vStatus = 307
lcInfo = [Temporary Redirect]
CASE m.vStatus = 400
lcInfo = [Bad Request]
CASE m.vStatus = 401
lcInfo = [Unauthorized]
CASE m.vStatus = 402
lcInfo = [Payment Required]
CASE m.vStatus = 403
lcInfo = [Forbidden]
CASE m.vStatus = 404
lcInfo = [Not Found]
CASE m.vStatus = 405
lcInfo = [Method Not Allowed]
CASE m.vStatus = 406
lcInfo = [Not Acceptable]
CASE m.vStatus = 407
lcInfo = [Proxy Authentication Required]
CASE m.vStatus = 408
lcInfo = [Request Timeout]
CASE m.vStatus = 409
lcInfo = [Conflict]
CASE m.vStatus = 410
lcInfo = [Gone]
CASE m.vStatus = 411
lcInfo = [Length Required]
CASE m.vStatus = 412
lcInfo = [Precondition Failed]
CASE m.vStatus = 413
lcInfo = [Request Entity Too Large]
CASE m.vStatus = 414
lcInfo = [Request-URI Too Long]
CASE m.vStatus = 415
lcInfo = [Unsupported Media Type]
CASE m.vStatus = 416
lcInfo = [Requested Range Not Suitable]
CASE m.vStatus = 417
lcInfo = [Expectation Failed]
CASE m.vStatus = 500
lcInfo = [Internal Server Error]
CASE m.vStatus = 501
lcInfo = [Not Implemented]
CASE m.vStatus = 502
lcInfo = [Bad Gateway]
CASE m.vStatus = 503
lcInfo = [Service Unavailable]
CASE m.vStatus = 504
lcInfo = [Gateway Timeout]
CASE m.vStatus = 505
lcInfo = [HTTP Version Not Supported]
ENDCASE
MESSAGEBOX( ;
[A problem has occured with the webservice] + CHR( 13 ) + lcInfo , ;
0+16+0, ;
[Web Processing Problem] ;
)
ENDFUNC
Im nächsten Kapitel geht es dann mit dem Empfang der Daten weiter...
Links zu den restlichen Kapiteln:
Einführung / Introduction
Teil 1: Abkürzungen und was sie bedeuten/ Abbreviations and their meaning
Teil 2: Wer ReST sagt, sagt auch JSON
/ In for a ReST, in for a JSON
Teil 3: Leerzeichen und andere Entitäten
/ BLANKS and other entities
Teil 4: JSON und der goldene Konverter
/ JSON and the golden converter
Teil 5: Die Startvorbereitungen
/ preparations for launch
Teil 6: Kleine Denkpause gefällig?
/ in need of a reflection period?
Teil 7: Fertig machen zur Landung
/ preparing for landing
Keine Kommentare:
Kommentar veröffentlichen