Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Netzwerke (https://www.delphipraxis.net/14-netzwerke/)
-   -   Delphi "Webservice" mit Indy und viele Fragen (https://www.delphipraxis.net/135819-webservice-mit-indy-und-viele-fragen.html)

wadriller 18. Jun 2009 11:35


"Webservice" mit Indy und viele Fragen
 
Hallo zusammen.

Hier mal unser "Ist-Zustand".

Wir haben eine ISAPI-DLL als Webservice laufen. Unsere Clientanwendung ist aktuell und Delphi 5 programmiert.
In dieser wird mittels Fastnet HTTP Komponente (bitte nicht schlagen) dieser Webservice in Form von

http://aaa.aaa.de/bbb.dll?cccccccccccccc

kontaktiert.

aaa -> Domainname (klar)
bbb -> Die ISAPI DLL
ccc -> Mehrere verschlüsselte Parameter

Soweit so klar (hoffe ich mal).
Der Webservice macht im Hintergrund mit den Parametern ein bischen was auf der Datenbank und liefert dann eine HTML Seite aus wo normal nur eine Zahl drauf steht. Der Client wertet dann den Body aus und macht damit weiter.

Ich vermute das wir das alles recht kompliziert gemacht haben, aber es läuft. ;-)

Jetzt steht aber eine Umstellung auf Delphi 2007 an. Und hier haben wir das Problem das es kein Fastnet mehr gibt.

Also "Soll-Zustand".
Der Client soll, wahrscheinlich mit Indy, die gleiche Funktion haben.

Die ersten Probleme haben sich jetzt bei mir schon aufgetan:

1. Wie kann ich einen Timeout bei Idhttp festlegen ?
2. Wie kann ich eine laufende Anfrage sauber abbrechen und danach eine neue mit neuen Parametern starten ?
3. Könnte ich die Funktion auch evtl. anders umsetzen ? Was bietet Indy hier sonst ? Es wäre auch kein Problem, wenns damit besser und stabil läuft den Webservice neu zu schreiben. Normal kommen von unterschiedlichen Clients aus dem Internet 5 - 10 Anfragen pro Sekunde beim Server an. Das sollte der neue Webservice dann auch verkraften.

Wer kann mir helfen und / oder Tipps geben ?

wadriller 30. Jun 2009 08:46

Re: "Webservice" mit Indy und viele Fragen
 
*Push*

Niemand eine Idee ??

alzaimar 30. Jun 2009 09:14

Re: "Webservice" mit Indy und viele Fragen
 
Hi, so richtig kenn ich mich zwar nicht mit Web-Techniken aus, aber ich würde mir mal einen richtigen Webservice schreiben. Ist total simpel, selbst ich hab das hinbekommen.

Zu deinen Fragen:
Du musst dafür sorgen, das Du die Arbeit unterbrechen kannst. Du könntest eine Eigenschaft 'Aborted' definieren, die Du von außen setzen kannst (auch über einen Timer, dann wäre dein Timeoutproblem gelöst). In deiner Abarbeitung fragst Du diese Eigenschaft immer mal wieder ab. Blöd wird es bei langwierigen SQL-Abfragen. Da weiss ich nicht, wie man soetwas unterbricht.

Ich würde die Arbeit in einem Try--Except kapseln. Beim Abbruch wirfst Du eine bestimmte Exception (oder einfach ein Abort) und wertest das im Except-Teil aus, etwa so:
Delphi-Quellcode:
// Hier könnte z.B. auch noch ein Timer gestartet werden, dessen Timer-Event die 'Aborted' Eigenschaft setzt.
// Obwohl das sinnlos wäre, wenn z.B. ein langes SQL-Statement abgearbeitet wird.
Try
  DoStep1;
  If Aborted Then Abort;
  DoStep2;
  If Aborted Then Abort;
  ...
  DoFinalStep;
Except
  On E:EAbort Do
    // Operation aborted;
  On E:Exception Do
    // Oh oh, etwas böses ist passiert
End;
  Aborted := False;

wadriller 30. Jun 2009 09:20

Re: "Webservice" mit Indy und viele Fragen
 
Hättest du evtl. eine gute Referenz wo ich mich mal in Webservices einlesen kann ?
In der COdelibary hab ich leider nichts gefunden

mjustin 30. Jun 2009 10:05

Re: "Webservice" mit Indy und viele Fragen
 
Zitat:

Zitat von wadriller
1. Wie kann ich einen Timeout bei Idhttp festlegen ?

Die ReadTimeOut Property bietet sich dafür an, TIdHTTP erbt sie von TIdTCPClientCustom. Wird das Timeout erreicht, wirft TIdHTTP eine Exception.

Die Fehlerbehandlung hängt natürlich von Feinheiten ab, die man genauer kennen muss:

* darf der Client den gleichen Request problemlos mehrmals senden (anders gesagt: macht der Request etwas, was er nur genau einmal tun darf)? Selbst wenn der Client keine Response erhält, könnte es ja sein, dass der Server den Request empfangen hat und auch verarbeitet hat.

* wie soll sich der Client verhalten, wenn der Server auf einen Request mehrmals nicht reagiert? Soll er den Request verwerfen (oder ihn in eine Art Warteschlange stellen) und mit dem nächsten weitermachen?

Viele Grüße,

wadriller 30. Jun 2009 10:14

Re: "Webservice" mit Indy und viele Fragen
 
Hi. Danke für deine Antwort.

Mit dem ReadTimeOut hatte ich auch getestet. Wenn der Server aber nicht erreichbar ist (hatte es mit einem lokalen IIS getestet) hat er bei mir den TimeOut nicht berücksichtigt.

Zu deinen Fragen.

Der Client darf die gleiche Anfrage mehrmals senden. Das ist kein Problem.

Man kann es sich so vorstellen. Du hast ein DBGrid mit x Datensätzen. Du machst den ersten Datensatz auf. Hier soll dann ein Request mit den Daten aus dem Datensatz gesenden werden. Das Formular das die Daten zeigt hat die möglichkeit durch die Daten zu scrollen.

Wenn ich jetzt als den Datensatz 1 auf mache wird die Anfrage mit den Daten geschickt. Während der Request noch läuft wird jetzt gescrollt. Daraufhin soll der Request zu Datensatz 1 abgebrochen werden und ein neuer für Datensatz 2 begonnen werden.

Wenn der Server nicht erreichbar ist, soll der Client einfach anzeigen "nicht erreichbar" mehr nicht, da die Software auch auf Rechnern ohne Internet eingesetzt wird (der Service ist nicht die Hauptfunktion der Software).

mjustin 30. Jun 2009 10:40

Re: "Webservice" mit Indy und viele Fragen
 
Zitat:

Zitat von wadriller
Hi. Danke für deine Antwort.

Mit dem ReadTimeOut hatte ich auch getestet. Wenn der Server aber nicht erreichbar ist (hatte es mit einem lokalen IIS getestet) hat er bei mir den TimeOut nicht berücksichtigt.

TIdTCPClientCustom hat auch eine ConnectTimeout property (standardmäßig braucht das Timeout unter Windows relativ lange).

Einen HTTP Request einfach mittendrin abbrechen ist ohne Eingriffe in Indy nicht einfach.

Mit den passenden Timeout Werten ist es aber wahrscheinlich auch nicht erforderlich, am Indy Source zu basteln. Eine simple Möglichkeit wäre, den ersten Timeout schon als Anzeichen dafür zu sehen, dass die Verbindung gestört ist, und dann vorerst keine weiteren Requests zu senden (Offline-Modus). Als zweite Möglichkeit wären Threads geeignet, die würde ich aber erst mal vermeiden.

Viele Grüße,

wadriller 30. Jun 2009 10:46

Re: "Webservice" mit Indy und viele Fragen
 
Wüsste auf Anhieb nicht wie ich den "Offline-Mode" so einfach hin bekomme, da zwischenzeitlich ja der Rechner irgendwann wieder online kommen kann.

Die Aktuelle "Fastnet"-Variante die bei den Kunden draußen ist läuft momentan auch mit einem Thread, da die Anwendung während dem HTTP.GET weiter bedient werden soll.

Welche Möglichkeit gäbe es denn über Internet sonst zu kommunizieren (also ohne HTTP). Ich muss meinem Server nur einen Parameterstring mitteilen und der Server muss nach einer SQL Abfrage eine Zahl rückliefern. Das geht doch bestimmt ohne HTTP, oder ?

mjustin 30. Jun 2009 10:55

Re: "Webservice" mit Indy und viele Fragen
 
Zitat:

Zitat von wadriller
Wüsste auf Anhieb nicht wie ich den "Offline-Mode" so einfach hin bekomme, da zwischenzeitlich ja der Rechner irgendwann wieder online kommen kann.

Ich hatte den Satz "Wenn der Server nicht erreichbar ist, soll der Client einfach anzeigen "nicht erreichbar" mehr nicht, da die Software auch auf Rechnern ohne Internet eingesetzt wird (der Service ist nicht die Hauptfunktion der Software)." so verstanden, dass der Client bei einem Verbindungsausfall etwas anzeigt, und dann ohne Webservice weiterarbeitet. 'Offline' war nur meine Umschreibung von 'nicht erreichbar'.

Ich würde also bei einem Ausfall eine Meldung ausgeben (Message oder Statuszeile), und dem Benutzer die Möglicheit geben über einen Menüpunkt oder eine Taste wieder den Kontakt zum Server zu aktivieren.

HTTP hat den Vorteil dass die meisten Firewalls den dazu erforderlichen Port 80 (oder 443 für HTTPS) freigeschaltet haben. Für eine Internet-Anwendung ist HTTP daher sehr wartungsfreundlich.

Viele Grüße,

wadriller 30. Jun 2009 10:59

Re: "Webservice" mit Indy und viele Fragen
 
Wartungsfreundlich stimmt.

Aber ich hätte auch kein Problem einen Port x zu nutzen der dann offen sein muss ;-)

Ansonsten werden wir wohl auf HTTP bleiben


Alle Zeitangaben in WEZ +1. Es ist jetzt 15:31 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz