![]() |
idhttpserver mehere Anfragen gleichzeitig verarbeiten
Hallo Leute also ich habe da ein Problem
in der Function procedure TForm1.IdHTTPServer1CommandGet(AThread: TIdPeerThread; ARequestInfo: TIdHTTPRequestInfo; AResponseInfo: TIdHTTPResponseInfo); verarbeite ich die Requestinfo und die response info. Probelm dabei ist wenn ich mit einem testtool 2 oder mehr gleichzeitige verbindungen an den HTTP Server schicke bekomme ich zu viele Parameter bzw. Parameter doppelt. sieht wie folgt aus
Delphi-Quellcode:
procedure TForm1.IdHTTPServer1CommandGet(AThread: TIdPeerThread;
ARequestInfo: TIdHTTPRequestInfo; AResponseInfo: TIdHTTPResponseInfo); var lGWDataService: IGWDataService; I : integer; sl : TStringlist; sl1 : TStringlist; sl2 : TStringlist; ergebnis : String; starttime : TTime; endtime : TTime; begin AThread.Start; starttime := now; meparams.Lines := ARequestInfo.Params; meparams.Lines.add(''); meparams.Lines.add(inttostr(AThread.ThreadID)); sl := Tstringlist.create; sl1 := Tstringlist.create; sl2 := Tstringlist.create; application.ProcessMessages; for I := 0 to meparams.Lines.Count -1 do begin if pos('VO=',meparams.Lines.Strings[i]) > 0 then splitstring(meparams.lines.Strings[i],'=',sl); if pos('NA=',meparams.Lines.Strings[i]) > 0 then splitstring(meparams.lines.Strings[i],'=',sl1); end; application.ProcessMessages; AResponseInfo.ResponseNo := 0; AResponseInfo.ResponseText := ''; application.ProcessMessages; // Abfrage in einer DB auf Vorname und nachname splitstring(ergebnis,'-',sl2); AResponseInfo.ResponseNo := strtoint(trim(sl2[0])); AResponseInfo.ResponseText := sl2[1]; AResponseInfo.WriteHeader; AResponseInfo.WriteContent; endtime := now; melog.lines.Add('Aufruf des Service zu Verarbeitung : ' +Formatdatetime('ss.zzz',endtime - starttime)+' mit der Session ID = '+inttostr(AThread.ThreadID)); application.ProcessMessages; melog.refresh; sl.free; sl1.free; sl2.free; AThread.Terminate; end; und so wie das jetzt aussieht bekomme ich in den Params teilweise zu viele Parameter und uin dem testtool gibts die Meldung das die Webseite nicht angezeogt werden kann. Aufruf des Servers mit Parameter sieht so aus: // ![]() Achja Turbo Delphi 2006 und Indy 9 |
Re: idhttpserver mehere Anfragen gleichzeitig verarbeiten
Also ich hab mit Indy9 das Problem bisher noch nicht gehabt. Bei dir sind mir aber ein paar Sachen aufgefallen, die nicht so dolle sind:
- AThread.Start und AThread.Terminate sind komplett unnötig, da der Thread schon gestartet ist. - Das Event wird von dem Thread ausgelöst und arbeitet ohne Synchronize(); . Somit sind VCL-Aufrufe innerhalb des Threads ohne Synchronize verboten. Genauso ist es mit Application.ProcessMessages;. Du musst das nicht ausführen, da sowieso alles in einem Thread ausgeführt wird und die Hauptanwendung somit nicht beeinträchtigt wird (kannst ja mal in dem Event zum Spaß ein Sleep(1000000); einbauen und du wirst sehen, dass die Anwendung währenddessen ganz normal weiterläuft). Ich glaube dein Problem ist, dass du aus dem Thread-Event heraus auf die VCL zugreifst (z.B. melog.lines.Add) und dein Programm somit früher oder später sich selbst zerschießt. Außerdem: warum speicherst du die Parameter erst in einem Memo, dass du dann später wieder auswertet?
Delphi-Quellcode:
Wenn jetzt mehrere Request auf einmal kommen, kann der Inhalt von meparams totaler Schwachsinn werden, da du NICHT Synchronisierst!
meparams.Lines := ARequestInfo.Params;
meparams.Lines.add(''); meparams.Lines.add(inttostr(AThread.ThreadID)); In diesem Event musst du komplett Thread-Save arbeiten: kein Zugriff auf die VCL ohne Synchronize, Critical-Sections für andere Sachen usw. Jedoch ist es in dem Event nicht sinnvoll, es zu synchronisieren. Wenn du das machst, ist der große Vorteil - nähmlich dass jede Verbindung ihren eigenen Thread hat - aufeinmal weg. Am besten wäre es, wenn du in diesem Event auf keine VCL-Sachen zugreifst (Buttons usw.). StringListen sind kein Problem - solange sie nur in einem Thread verwendet werden (ist bei dir mit sl, sl1, sl2 ja so). Aber auf Memos in der Hauptform solltest du nicht zugreifen, da dadurch 1. nur unnötiger Aufwand wegen Synchronisierung entsteht und 2. weil dann der Thread-Vorteil dahin ist. Ich schreib mal das Event für dich etwas um:
Delphi-Quellcode:
(nicht geprüft, da Delphi nicht offen)
uses
SyncObjs; var logCritical : TCriticalSection; logMessage : string; procedure TForm1.SyncLogMessage; begin melog.Lines.Add(logMessage); end; procedure TForm1.DoLogMessage(AThread: TIdPeerThread; msg: string); begin // diese Critical-Section ist dafür da, dass nicht mehrere Threads gleichzeitig // die globale Variable "logMessage" bearbeiten können logCritical.Enter; try logMessage := msg; AThread.Synchronize(SyncLogMessage); finally logCritical.Leave; end; end; procedure TForm1.IdHTTPServer1CommandGet(AThread: TIdPeerThread; ARequestInfo: TIdHTTPRequestInfo; AResponseInfo: TIdHTTPResponseInfo); var sl, sl1, sl2 : TStringlist; StartTime, EndTime : TDateTime; lGWDataService : IGWDataService; i : integer; Ergebnis : string; begin StartTime := Now; // Objekte erzeugen sl := TStringList.Create; sl1 := TStringList.Create; sl2 := TSTringList.Create; try for i:=0 to ARequestInfo.Params.Count -1 do begin if Pos('VO=', ARequestInfo.Params.Strings[i]) > 0 then SplitString(ARequestInfo.Params.Strings[i], '=', sl); if Pos('NA=', ARequestInfo.Params.Strings[i]) > 0 then SplitString(ARequestInfo.Params.Strings[i], '=', sl1); end; // Abfrage in einer DB auf Vorname und nachname AResponseInfo.ResponseNo := 200; // HTTP-STATUS-OK AResponseInfo.ResponseText := sl2[1]; AResponseInfo.WriteHeader; AResponseInfo.WriteContent; EndTime := Now; DoLogMessage(AThread, 'Aufruf des Service zu Verarbeitung : ' + Formatdatetime('ss.zzz', EndTime - StartTime) + ' mit der Session ID = ' + IntToStr(AThread.ThreadID)); finally // Objekte wieder freigeben sl.Free; sl1.Free; sl2.Free; end; end; initialization LogCritical := TCriticalSection.Create; finalization LogCritical.Free; |
Re: idhttpserver mehere Anfragen gleichzeitig verarbeiten
Du musst sämtliche Zugriffe auf gemeinsame Ressourcen mit einer Critical Section versehen, da du sonst grundsätzlich Zugriffsverletzungen bekommen kannst / wirst.
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 05:41 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