AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Netzwerke Delphi idhttpserver mehere Anfragen gleichzeitig verarbeiten
Thema durchsuchen
Ansicht
Themen-Optionen

idhttpserver mehere Anfragen gleichzeitig verarbeiten

Ein Thema von Digielm · begonnen am 5. Aug 2008 · letzter Beitrag vom 5. Aug 2008
Antwort Antwort
Digielm

Registriert seit: 2. Aug 2006
246 Beiträge
 
Delphi 5 Enterprise
 
#1

idhttpserver mehere Anfragen gleichzeitig verarbeiten

  Alt 5. Aug 2008, 09:44
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:

// http://localhost:3131/?VO=Vorname&NA=Nachname



Achja Turbo Delphi 2006 und Indy 9
  Mit Zitat antworten Zitat
Benutzerbild von littleDave
littleDave

Registriert seit: 27. Apr 2006
Ort: München
556 Beiträge
 
Delphi 7 Professional
 
#2

Re: idhttpserver mehere Anfragen gleichzeitig verarbeiten

  Alt 5. Aug 2008, 13:17
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:
meparams.Lines := ARequestInfo.Params;
meparams.Lines.add('');
meparams.Lines.add(inttostr(AThread.ThreadID));
Wenn jetzt mehrere Request auf einmal kommen, kann der Inhalt von meparams totaler Schwachsinn werden, da du NICHT Synchronisierst!

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:
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;
(nicht geprüft, da Delphi nicht offen)
Jabber: littleDave@jabber.org
in case of 1 is 0 do external raise while in public class of object array else repeat until 1 is 0
  Mit Zitat antworten Zitat
Benutzerbild von SubData
SubData

Registriert seit: 14. Sep 2004
Ort: Stuhr
1.078 Beiträge
 
Delphi 11 Alexandria
 
#3

Re: idhttpserver mehere Anfragen gleichzeitig verarbeiten

  Alt 5. Aug 2008, 13:43
Du musst sämtliche Zugriffe auf gemeinsame Ressourcen mit einer Critical Section versehen, da du sonst grundsätzlich Zugriffsverletzungen bekommen kannst / wirst.
Ronny
/(bb|[^b]{2})/
  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 06: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