Einzelnen Beitrag anzeigen

Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
43.115 Beiträge
 
Delphi 12 Athens
 
#6

AW: Datasnap REST im Apache, Download einer Datei dauert sehr lange

  Alt 18. Jun 2014, 15:47
[add]
Zitat:
Warum streamst Du diese nicht direkt an den Client?
Wir hatten das Anfangs auch parallel zum DataSnap via Indy (TCP) übertragen und über DataSnap nur die Übertragung gesteuert. (Teilweise über DataSnap-Callbacks)
Aber als wir dann rausfanden, warum größere Dateien "nicht" übertragen wurden (falsche Auswertung des Streams), baute ich das dann wieder so um, daß es jetzt nur noch via DataSnap läuft.
[/add]


PS: (Ob das wirklich bei REST geht, weiß ich nicht ... ich glaub wir verwenden JSON oder so ... hab's jetzt nicht mehr im Kopf)

Delphi-Quellcode:
function TServerMethods1.GetFile(Filename, Version: string): TStream;
begin
  Result := GetFile(Filename, Version);
  if Result.Size <= 0 then begin
    Result.Free;
    StringToLogfile(logFileError, 'GetFile: Datei ' + Filename + ' nicht gefunden');
    raise Exception.Create('GetFile: Datei ' + Filename + ' nicht gefunden');
  end;
  StringToLogfile(logFileInfo, 'GetFile: Datei ' + Filename + ' wurde gefunden');
end;
Auf Clientseite bekommt man da eine Art TMemoryStream an ('ne eigene Klasse des DataSnap), welchen man automatisch vom DataSnap freigeben lassen kann (dem automatisch generierten Client-Modul) oder man gibt es dann selber frei, wenn man es ausgelesen hat.

Delphi-Quellcode:
// Auf Serverseite, wenn man da einen Stream hin überträgt (automatische Freigabe):
procedure TDSFileMethods.Xyz(Stream: TStream);
begin
  ...
  MachWas(Stream);
  ...
end;

// Auf Clientseite, wenn ein Stream abgerufen wurde (manuelle Freigabe):
var
  Stream: TStream;
begin
  Stream := DataSnapClientModul.GetStream(...);
  try
    ...
    MachWas(Stream);
    ...
  finally
    Stream.Free;
  end;
end;

// Auf Clientseite, wenn ein Stream abgerufen wurde (automatische Freigabe):
var
  Stream: TStream;
begin
  Stream := DataSnapClientModul.GetStream(...);
  ...
  MachWas(Stream);
  ...
end;
Aber wenn du den Stream an eine Komponente weitergeben willst, dann empfehle ich dir den im Clienten umzukopieren, bevor er benutzt wird, denn .Size funktioniert nicht.
Delphi-Quellcode:
procedure FileMethods_CopyStream(Source, Dest: TStream);
var
  B: array[1..64*1024] of Byte;
  i: Integer;
begin
  Source.Position := 0;
  repeat
    i := Source.Read(B, SizeOf(B));
    Dest.WriteBuffer(B, i);
  until i < SizeOf(B);
end;

// Auf Serverseite, wenn man da einen Stream hin überträgt (automatische Freigabe):
procedure TDSFileMethods.Xyz(Stream: TStream);
var
  Temp: TStream;
begin
  Temp := TMemoryStream.Create;
  try
    FileMethods_CopyStream(Stream, Temp);
    ...
    MachWas(Temp);
    ...
  finally
    Temp.Free;
  end;
end;

// Auf Clientseite, wenn ein Stream abgerufen wurde (manuelle Freigabe):
var
  Temp, Stream: TStream;
begin
  Temp := TMemoryStream.Create;
  try
    Stream := DataSnapClientModul.GetStream(...);
    try
      FileMethods_CopyStream(Stream, Temp);
    finally
      Stream.Free;
    end;
    ...
    MachWas(Temp);
    ...
  finally
    Temp.Free;
  end;
end;

// Auf Clientseite, wenn ein Stream abgerufen wurde (automatische Freigabe):
var
  Temp: TStream;
begin
  Temp := TMemoryStream.Create;
  try
    FileMethods_CopyStream(DataSnapClientModul.GetStream(...), Temp);
    ...
    MachWas(Temp);
    ...
  finally
    Temp.Free;
  end;
end;
Garbage Collector ... Delphianer erzeugen keinen Müll, also brauchen sie auch keinen Müllsucher.
my Delphi wish list : BugReports/FeatureRequests

Geändert von himitsu (18. Jun 2014 um 15:59 Uhr)
  Mit Zitat antworten Zitat