Hi Bernhard,
habe mir gerade nur den Code im Server angeschaut und da sind mir
auf Anhieb ein paar Probleme aufgefallen:
- Im OnExecute des IndyServers muss der komplette Code Thread-Safe sein,
weil er innerhalb des Conntext eines Threads abläuft, das bedeutet sämtliche
VCL-
Gui Zugriffe müssen Thread-Safe sein:
Memo1.lines.add('blaBla');
Geht so nicht. Auch der Zugriff auf gemeinsame Ressourcen muss geschützt sein,
Delphi-Quellcode:
public
{ Public-Deklarationen }
abmp: TBitMap; // <---- nicht Thread-Safe
aMyRecordIndy: TMyThreadSafeRecord;
// ^^ hört sich Thread Safe ein, aber wenn 2 Clients gleichzeitig connecten
// und den Record benutzen, was passiert dann ?
BEnutzung des Bmps:
Delphi-Quellcode:
3:
begin
///
Memo1.Lines.Add('record received AND JOB done!');
abmp.Height := 300;
abmp.Width := 300;
DrawRandomBitMap(abmp);
ServerImage.Picture.Bitmap.Assign(abmp);
// Jeder Client braucht sein eigenes Bmp !!
Des Weiteren habe ich im
SVN nicht die Units gefunden:
Unit_Indy_Functions, Unit_Indy_Classes;
Wenn die Function SendStream dort noch wie in den anderen Threads von Dir so existiert,
das
Delphi-Quellcode:
result := false;
try
// sende ...
// ...
finally
// ...
end;
result := true; // wird immer gesetzt, egal ob ein Fehler auftritt oder nicht
Des Weiteren solltest Du solche Boolean Vergleiche lassen:
Delphi-Quellcode:
if (SendBuffer(AContext, LBuffer) = False) then // falsch, gibts genug Threads zu dem Thema
// richtig:
if not (SendBuffer(AContext, LBuffer)) then ...
Einen letzten Tipp habe ich für Dich noch; Ich würde(so mache ich es meistens auf jeden Fall)
eine Klasse TMyClient definieren diese pro Connection wie folgt verwenden:
Delphi-Quellcode:
// Im OnConnect
AContext.Data := TMyClient.Create;
// Im OnDisConnect:
If Assigned(AContext.Data)
then
begin
if AContext.Data
is TMyClient
then
TMyClient(AContext.Data).Free;
AContext.Data :=
nil;
// auf jeden Fall auf nil setzen, sonst versucht Indy das ganze freizugeben
end;
// Im OnExecute
var myClient : TMyClient;
begin
// ....
try
myClient := TMyClient(AContext.Data);
except
myClient :=
nil;
end;
if Assigned(myClient)
then
begin
// je nach Definition des TMyClients Object hast Du jetzt geschützte Ressouren pro Client
// also Daten/Infos darein oder als lokale Var im OnExecute des Servers
end;
// ...
Hoffe das bringt Dich ein wenig weiter,
Greetz Data
Der Horizont vieler Menschen ist ein Kreis mit Radius Null, und das nennen sie ihren Standpunkt.