AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Netzwerke Webserveranwendung: EXE ruft ISAPI
Thema durchsuchen
Ansicht
Themen-Optionen

Webserveranwendung: EXE ruft ISAPI

Ein Thema von Delbor · begonnen am 22. Aug 2014 · letzter Beitrag vom 25. Aug 2014
Antwort Antwort
Delbor

Registriert seit: 8. Okt 2006
Ort: St.Gallen/Schweiz
1.192 Beiträge
 
Delphi 11 Alexandria
 
#1

AW: Webserveranwendung: EXE ruft ISAPI

  Alt 23. Aug 2014, 18:27
Hi Olly73


Aber genau da hörte bisher mein Verständnis auf, da ich so zwar 2 Isapi-Dlls in den IIS eingebunden hätte - aber eben ohne, dass die eine von der anderen etwas weiss.
Die einzige 'Verbindung' wäre wohl eine gemeinsam genutzte DB gewesen.
Ja, in diesem Fall ist die "Verbindung" die Datenbank oder man nutzt HTTP-Requests untereinander.
Ja, sowas habe ich mir auch gedacht, konnte mir die Sache aber nicht so richtig vorstellen. Vielleicht löst sich der Nebel aber langsam. Zum einen laufen Filter-Dlls ja nicht nur pro Anfrage, sondern permanent (so lange die IIS laufen), zum andern habe ich hier ein Beispiel, wie eine Isapi-Extension eine andere aufruft.
Diese beiden Beispiele hätte ich mir gerne per schrittweisem durchsteppen etwas näher angeschaut, doch wie geschrieben, konnte ich die IIS nie dazu übereden, mir die Seiten aus meinem eigenen Webbroker-Projekt auch anzuzeigen.
Zusammen mit der EXE klappt das aber, und gesetzte Haltepunkte werden auch angesprungen.

ABER: Ich habe immer noch nicht verstanden, warum du 2 getrennte ISAPIs/EXEs benötigst und nicht gleich alles in eine ISAPI packst?!
Na ja. Auslöser war das Eliza-Beispiel der Indys mit dem HTTP-Server, das mir auch angezeigt wurde, nachdem ich die IIS zwischenzeitlich rausgeworfen habe - wobei ich jetzt ja anstelle des IdHTTPServers die Webbrokerbridge verwende. Wie oben schon gesagt: mit der Exe bin ich unabhängig von den IIS.
Ein weiterer Grund war aber eben auch: Mit einer Filter-Isapi und einer Isapi-Extension hätte ich offensichtlich/scheinbar zwei unabhängige Projekte gehabt und habe mir zumindest vorerst absolut nicht vorstellen können, wie die beiden zusammenarbeiten,
Dazu kommt - eine EXE gibt mir die Möglichkeit, Programmlogik an einem Ort zu verarbeiten (Sessions, Cookies), wie ich das sonst auch mache.

Etwas anderes sollte vielleicht auch nicht ausser acht gelassen werden: Microsoft selbst beschreibt die ISAPI-Filter als veraltet; man solle an ihrer Stelle doch eher Module definieren. Und wenn ich richtig gelesen habe, können die auch executables sein.

Zitat:
...warum du 2 getrennte ISAPIs/EXEs benötigst
Es sind ja nicht zwei gtrennte(also je eine exe und eine Isapi) sondern je eine. Aber was du ansprichst, ist wohl eher die Projektgruppe mit den 2 separaten Projekten. Nun ja, die DL ist für sich ein eigenes Projekt, deshalb meine Überlegung mit der Projektgruppe.
Nachdem ich mir wie oben beschreiben, das ganze durch einfügen des Datemoduls zerschossen habe und eine neue DLL auch nicht viel änderte, werde ich wohl das ganze neu aufsetzen...


Das hier hätte ich beinahe überlesen:
Zitat:
...alles in eine ISAPI packst?!
Eine Webbrokeranwendung (Isapi) wird genau für jeweils einen Request ausgeführt, beantwortet diesen und wird dann beendet. Man kann das Webmodul zwar auch deaktivieren - es ist dann einfach 'geparkt' und kann bei Bedarf wieder aktiviert werden. Aber sie eignet sich nicht für ein Session-oder Cookie-Managment.
Und eine Session in die DB zu schreiben, solange sie nicht beendet wird, denke ich, sollte im Interesse der Performance wohl besser unterbleiben. Ich denke, das ergibt viel zu viele Datenbankzugriffe, vor allem, wenn ich auch anonyme Zugriffe über Sessions ablaufen.

Gruss
Delbor
Roger
Man muss und kann nicht alles wissen - man muss nur wissen, wo es steht.
Frei nach Albert Einstein
http://roase.ch
  Mit Zitat antworten Zitat
Benutzerbild von Olli73
Olli73

Registriert seit: 25. Apr 2008
Ort: Neunkirchen
777 Beiträge
 
#2

AW: Webserveranwendung: EXE ruft ISAPI

  Alt 23. Aug 2014, 19:35
Das hier hätte ich beinahe überlesen:
Zitat:
...alles in eine ISAPI packst?!
Und dabei war das (zumindest für mich) das Wichtigste.

Eine Webbrokeranwendung (Isapi) wird genau für jeweils einen Request ausgeführt, beantwortet diesen und wird dann beendet. Man kann das Webmodul zwar auch deaktivieren - es ist dann einfach 'geparkt' und kann bei Bedarf wieder aktiviert werden. Aber sie eignet sich nicht für ein Session-oder Cookie-Managment.
Nö. Wenn die ISAPI einmal geladen ist, verbleibt sie normalerweise im Speicher; es sei denn du setzt absichtlich den Registryeintrag "CacheExtensions" auf 0:

http://msdn.microsoft.com/de-de/libr...(v=vs.71).aspx

Aber davon wird explizit abgeraten, außer zum Debuggen.

Mit UniGui (unigui.com) kann man auch eine ISAPI-DLL erstellen und die ist "statefull" (hält also Daten für jede aktive Session im Speicher)!

Und eine Session in die DB zu schreiben, solange sie nicht beendet wird, denke ich, sollte im Interesse der Performance wohl besser unterbleiben. Ich denke, das ergibt viel zu viele Datenbankzugriffe, vor allem, wenn ich auch anonyme Zugriffe über Sessions ablaufen.
Du kannst die Daten auch im Speicher behalten, musst aber ein paar Dinge beachten:

Globale Variablen sind grundsätzlich Pfui, da multithreaded, und müssen durch critical sections abgesichert werden. Aber als globale Variable brauchst du eigentlich nur eine SessionList (Liste, Array, Hashmap, ...). Diese ist durch eine CriticalSection abzusichern.

In die einzelnen Sessions (Session-Objekte) kannst du dann deine Daten, (Daten-)Objekte, Datenmodule etc. packen. Dabei muss ein Objekt oder Datenmodul für jede Session neu erstellt werden und es dürfen auch dort keine globalen Variablen, sondern nur Felder/Properties verwendet werden.

Gruß
Olli
  Mit Zitat antworten Zitat
Delbor

Registriert seit: 8. Okt 2006
Ort: St.Gallen/Schweiz
1.192 Beiträge
 
Delphi 11 Alexandria
 
#3

AW: Webserveranwendung: EXE ruft ISAPI

  Alt 23. Aug 2014, 22:43
Hi Olli73

Zitat:
Nö. Wenn die ISAPI einmal geladen ist, verbleibt sie normalerweise im Speicher; es sei denn du setzt absichtlich den Registryeintrag "CacheExtensions" auf 0:
Ups! Ich habe da zwar - von Embaecadero - andere Infos:
Jede Anforderung wird in einem eigenen Thread behandelt.

Ich habe jetzt doch eine Weile gesucht und bislang nur oben verlinkte Seite gefunden, die meine Aussage unterstützt.
Aber vielleicht sollten ich doch mal ein Missverständnis ausräumen: Ich wollte nicht behaupten, dass die dll aus dem Speicher entfernt wird:
Zitat:
Eine Webbrokeranwendung (Isapi) wird genau für jeweils einen Request ausgeführt, beantwortet diesen und wird dann beendet
Das stimmt so wirklich nicht. Es geht darum, dass ISAPI für jeden Request einen Thread startet - und dieser wird beendet, wenn die Anfrage fertig bearbeitet ist.

Zitat:
Globale Variablen sind grundsätzlich Pfui, da multithreaded, und müssen durch critical sections abgesichert werden. Aber als globale Variable brauchst du eigentlich nur eine SessionList (Liste, Array, Hashmap, ...). Diese ist durch eine CriticalSection abzusichern.

In die einzelnen Sessions (Session-Objekte) kannst du dann deine Daten, (Daten-)Objekte, Datenmodule etc. packen. Dabei muss ein Objekt oder Datenmodul für jede Session neu erstellt werden und es dürfen auch dort keine globalen Variablen, sondern nur Felder/Properties verwendet werden.
Es ist jetzt schon eine Weile her, dass ich selbst mit Threads gearbeitet habe. Was mir davon so aus dem Stegreif noch geblieben ist: ein Thread eines (Desktop-)Programmes kann nicht auf ein VCL-Objekt zugreifen, ausser durch Synchronisierung. Das aber kann den Performancevorteil eines Threads zunichte machen. Ein (Session-)Objekt müsste also dem Thread vor/beim Start übergeben werden.

Ich hab jetzt gerade noch etwas in den Sourcen gestöbert. Bislang hatte ich geglaubt, durch die Verwendung der Isapi-Units, die Delphi mitliefert, würde ein Thread automatisch gestarte, konnte bislang aber keinen Code finden, der sowas macht...
Solche Aussaggen veranlassten mich zu dieser Annahme:
Na ja, mir schwant, dass ein ausführliches Studium zuverlässiger als die Embarcadero-Help ist...

Andrerseits - was ist eigentlich genau die Aufgabe der IIS? Sorgen die für den ThreadStart? Da sind leider keine Sourcen dabei, wo man selbst nachsehen könnte, was genau abläuft.

Das mit den globalen Variablen war mir bekannt: Das war für mich einer, wenn nicht gar der Hauptgrund, für eine EXE.


Gruss
Delbor
Roger
Man muss und kann nicht alles wissen - man muss nur wissen, wo es steht.
Frei nach Albert Einstein
http://roase.ch
  Mit Zitat antworten Zitat
Benutzerbild von Olli73
Olli73

Registriert seit: 25. Apr 2008
Ort: Neunkirchen
777 Beiträge
 
#4

AW: Webserveranwendung: EXE ruft ISAPI

  Alt 24. Aug 2014, 01:51
Zitat:
Nö. Wenn die ISAPI einmal geladen ist, verbleibt sie normalerweise im Speicher; es sei denn du setzt absichtlich den Registryeintrag "CacheExtensions" auf 0:
Ups! Ich habe da zwar - von Embaecadero - andere Infos:
Jede Anforderung wird in einem eigenen Thread behandelt.

Ich habe jetzt doch eine Weile gesucht und bislang nur oben verlinkte Seite gefunden, die meine Aussage unterstützt.
Da steht "eigner Thread". Und das ist korrekt. Aber es ist immer nur ein Prozess und daher ist es auch ein gemeinsamer Speicherbereich. Man muss lediglich mit den Speicherzugriffen aufpassen (kritische Abschnitte verwenden).

Zitat:
Aber vielleicht sollten ich doch mal ein Missverständnis ausräumen: Ich wollte nicht behaupten, dass die dll aus dem Speicher entfernt wird:
Zitat:
Eine Webbrokeranwendung (Isapi) wird genau für jeweils einen Request ausgeführt, beantwortet diesen und wird dann beendet
Das stimmt so wirklich nicht. Es geht darum, dass ISAPI für jeden Request einen Thread startet - und dieser wird beendet, wenn die Anfrage fertig bearbeitet ist.
Ich bin mir jetzt nicht sicher, wie es bei ISAPI ist, aber wenn du eine "Webbroker-EXE" erstellst, gibt es einen Thread-Pool, d.h. es gibt auch dort mehrere Threads, die werden aber nicht sofort beendet, sondern werden der nächsten Anfrage (eines beliebigen Clients!) erneut zugeteilt. Macht daher letztlich keinen Unterschied, da der Client/Browser bei jeder Anfrage in einem anderen Thread landen kann. Wenn du also z.B. im Webmodul ein Dataset offen lässt, greift später ggf. ein ganz anderer Client auf dieses zu.

Zitat:
Zitat:
Globale Variablen sind grundsätzlich Pfui, da multithreaded, und müssen durch critical sections abgesichert werden. Aber als globale Variable brauchst du eigentlich nur eine SessionList (Liste, Array, Hashmap, ...). Diese ist durch eine CriticalSection abzusichern.
In die einzelnen Sessions (Session-Objekte) kannst du dann deine Daten, (Daten-)Objekte, Datenmodule etc. packen. Dabei muss ein Objekt oder Datenmodul für jede Session neu erstellt werden und es dürfen auch dort keine globalen Variablen, sondern nur Felder/Properties verwendet werden.
Es ist jetzt schon eine Weile her, dass ich selbst mit Threads gearbeitet habe. Was mir davon so aus dem Stegreif noch geblieben ist: ein Thread eines (Desktop-)Programmes kann nicht auf ein VCL-Objekt zugreifen, ausser durch Synchronisierung. Das aber kann den Performancevorteil eines Threads zunichte machen. Ein (Session-)Objekt müsste also dem Thread vor/beim Start übergeben werden.
Da du hier eh nicht mit visuellen Komponenten arbeiten kannst, macht es das schon mal etwas einfacher. Das Synchronize wird meist benutzt, um die Oberfläche/Forms anzupassen, das entfällt ja hier. Ansonsten benötigst du eigentlich nur eine globale Variable (oder besser eine Function oder noch besser eine Klassenmethode) mit einer "SessionList" über die du an ein bestimmtes Datenobjekt oder eine bestimmte Instanz eines Datenmoduls herankommst. Die Sessionlist und ggf. das Datenobjekt/Datenmodul musst du mit einer CriticalSection absichern, damit eben sicher gestellt ist, dass sich die Threads nicht in die Quere kommen. Wenn du mit Datenbanken arbeitest, musst du auch pro Session eine Datenbankverbindung aufbauen, wenn deine Datenbank-Connection-Komponente nicht explizit als Threadsafe gekennzeichnet ist.

Wenn also eine neue Anfrage in deinem Webmodul landet, musst du zuerst über die sessionList (unter Beachtung der CriticalSection!) aufrufen und dir darüber deine Daten für diese Session besorgen, bzw. einen neuen Eintrag in der Liste anlegen und eine neue Instanz der Datenstruktur erstellen, wenn es eine neue Session ist (der Client benötigt dann auch diese Session-ID und muss die beim nächsten mal mitsenden).

Zitat:
Ich hab jetzt gerade noch etwas in den Sourcen gestöbert. Bislang hatte ich geglaubt, durch die Verwendung der Isapi-Units, die Delphi mitliefert, würde ein Thread automatisch gestarte, konnte bislang aber keinen Code finden, der sowas macht...
Das passiert AFAIK irgendwo (tief) in den Indy-Komponenten.

Stimmt ja auch, ABER (s.o.): Thread != Prozess

Zitat:
Na ja, mir schwant, dass ein ausführliches Studium zuverlässiger als die Embarcadero-Help ist...
Waren scheinbar nur die Begrifflichkeiten. Aber sowas passiert mir in anderen Fällen auch ständig.

Zitat:
Das mit den globalen Variablen war mir bekannt: Das war für mich einer, wenn nicht gar der Hauptgrund, für eine EXE.
Da hilft dir eine "Webbroker-EXE" aber auch nicht weiter, da es dort das Gleiche mit den Threads ist (s.o.). Und ein CGI ist sogar ein eigener Prozess, also noch weniger für dich geeignet.


Gruß,
Olli
  Mit Zitat antworten Zitat
Delbor

Registriert seit: 8. Okt 2006
Ort: St.Gallen/Schweiz
1.192 Beiträge
 
Delphi 11 Alexandria
 
#5

AW: Webserveranwendung: EXE ruft ISAPI

  Alt 24. Aug 2014, 13:20
Hi Olli
Zitat:
Da hilft dir eine "Webbroker-EXE" aber auch nicht weiter, da es dort das Gleiche mit den Threads ist (s.o.). Und ein CGI ist sogar ein eigener Prozess, also noch weniger für dich geeignet.
Die Webbroker-Anwendung befindet sich nach wie vor in einer eigenen Datei - eben der DLL, wie sie von Delphi erstellt wird. Die exe ist eine normale Form, zur Zeit ohne jegliche visuellen Komponenten.
Die wohl wichtigste Klasse ist hier TIdWebbrokerBriodge, über die die Webbroker-Anwendung, bzw die erzeugte dll, aufgerufen wird - aber deswegen wohl die Apostrophe.

Zitat:
Da du hier eh nicht mit visuellen Komponenten arbeiten kannst, macht es das schon mal etwas einfacher.
Soweit ich dies in Erinnnerung habe, ist ein Synchronize immer dann nötig, wenn auf eine Klasse zugegriffen werden soll, die im Hauptthread abläuft, ob sie nun visuell ist oder nicht.

Mein vorheriges Projekt war eine Bilderdatenbank. Für die hatte ich eine Klasse erstellt, die die Daten aus einer SQL-Anfrage übernimmt (ein DS pro Instanz). Dasselbe gedachte ich eigentlich hier zu realisieren. Kurz skizziert:
  • eine Klasse wird von TThread abgeleitet(TCustomThrread?)
  • Die Klasse erhält(Stream-)Felder, für jedes DB-Feld eines. Ein 'Speicherzugriff' ist somit nach dem Start nur innerhalb des Threads nötig.

Aber bevor ich das realisiere, muss ich mir über den genauen Ablauf klar werden - wenn nämlich der Isapi-Tread entegegen meiner bisherigeen Erkenntnis trotzdem automatisch gestartet wird, wird es... na ja, sagen wir mal: interessant.

Gruss
Delbor
Roger
Man muss und kann nicht alles wissen - man muss nur wissen, wo es steht.
Frei nach Albert Einstein
http://roase.ch
  Mit Zitat antworten Zitat
Benutzerbild von Sir Rufo
Sir Rufo

Registriert seit: 5. Jan 2005
Ort: Stadthagen
9.454 Beiträge
 
Delphi 10 Seattle Enterprise
 
#6

AW: Webserveranwendung: EXE ruft ISAPI

  Alt 24. Aug 2014, 13:31
@Delbor

Ein Synchronize ist eigentlich nur für die GUI notwendig. Alles andere kann man über die Synchro-Objekte so steuern, dass immer nur ein Thread-Kontext gleichzeitig zugreift (zugreifen kann)

Zudem wiegt man sich mit dem Synchronize auch in eine falsche Sicherheit.

Also erstelle die gemeinsam genutzten Klassen threadsafe und benutze die einfach (ohne Synchronize)
Kaum macht man's richtig - schon funktioniert's
Zertifikat: Sir Rufo (Fingerprint: ‎ea 0a 4c 14 0d b6 3a a4 c1 c5 b9 dc 90 9d f0 e9 de 13 da 60)
  Mit Zitat antworten Zitat
Delbor

Registriert seit: 8. Okt 2006
Ort: St.Gallen/Schweiz
1.192 Beiträge
 
Delphi 11 Alexandria
 
#7

AW: Webserveranwendung: EXE ruft ISAPI

  Alt 24. Aug 2014, 14:36
Hi Sir Rufo

Laut Help gilt das mit der falschen Sicherheit für CriticalSections ebenso wie für Synchronize. Ich denke mir, eine CriticalSection beim Create des Threads und bestücken seiner Felder sollte ausreichen, da der Thread zu seiner Laufzeit nur auf seinen eigenen Speicherbereich zugreift.

Gruss
Delbor
Roger
Man muss und kann nicht alles wissen - man muss nur wissen, wo es steht.
Frei nach Albert Einstein
http://roase.ch
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 19:51 Uhr.
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz