![]() |
Datasnap REST im Apache, Download einer Datei dauert sehr lange
Ich möchte über meinen REST-Webservice, den ich in einen Apache als ISAPI.dll eingebunden habe, Dateien herunterladen. Das klappt soweit, nur dauert es sehr lange.
Eine Datei (ca. 35 MB) wird aus einer Datenbank geholt und an den Client übertragen. Das dauert ca. 70 Sekunden, wenn ich die Methode des Webservice lokal aufrufe. (Übers Internet dauert es so ca. 5 Minuten!!!). Ca. 1-2 Sekunden dauert es, dann ist die Datei aus der Datenbank geholt. Die Übertragung findet als String statt. Habe es auch schon per TStream probiert. Dauert aber genauso lang. Hier meine Server-Methode:
Delphi-Quellcode:
Kann mir jemand weiterhelfen?
function TServerMethods1.GetFile(aFile, version: string): string;
var stream: TMemoryStream; begin stream := nil; result := '-1'; try stream := GetFile(aFile, version); if stream.Size > 0 then begin StringToLogfile(logFileInfo, 'GetFile: Datei ' + aFile+ ' wurde gefunden'); result := string(EncodeBase64(stream.Memory, stream.Size)); end else begin StringToLogfile(logFileError, 'GetFile: Datei ' + aFile+ ' nicht gefunden'); result := '-1814'; end; finally stream.Clear; stream.Free; end; end; Vielen Dank schon mal im Voraus! |
AW: Datasnap REST im Apache, Download einer Datei dauert sehr lange
Was für eine Zugang zum Internet hast Du? Grundsätzlich ist das ja nicht zu langsam (Upload).
|
AW: Datasnap REST im Apache, Download einer Datei dauert sehr lange
Base64 ist 1/3-tel größer, wie die Originaldaten, und ~46 MB zu übertragen dauert halt ein paar Sekündchen. (REST sollte das auch nicht als Unicode übertragen, sonst wäre es nochmal so viel)
Bei 5 Minuten wäre das dann ein Up-/Download von 1,2 MBit/s (falls ich mich nicht verschätzt hab) |
AW: Datasnap REST im Apache, Download einer Datei dauert sehr lange
Ca. 50.000 kB Download und 23.000 kB Upload
Wenn ich das ganze lokal teste, sollte das aber innerhalb von Sekunden geschehen oder? |
AW: Datasnap REST im Apache, Download einer Datei dauert sehr lange
Zitat:
In einem Windowsnetz kann man von von ca. 8MB/s bei einem 100MBit-Netz ausgehen, dann sollten die Daten in ein paar Sekunden übertragen sein. Du überträgst Sie aber nicht direkt, sondern wandelst diese zuerst in einen String um. Warum streamst Du diese nicht direkt an den Client? |
AW: Datasnap REST im Apache, Download einer Datei dauert sehr lange
[add]
Zitat:
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:
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.
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;
Delphi-Quellcode:
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.
// 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;
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; |
AW: Datasnap REST im Apache, Download einer Datei dauert sehr lange
50 MBit
Ich verscuhe das ganze morgen mal per TStream und werde dann Bescheid geben |
AW: Datasnap REST im Apache, Download einer Datei dauert sehr lange
Nja, das macht dann so maximal 5-7 MByte/s und dazu dann noch der Weg durchs Netz.
Und was hat die Gegenseite? Und, du kannst problemlos Exceptions benutzen, denn DataSnap überträgt sie auch. Ich hab nochmal einen meiner Threads rausgekramt. ![]() Bis standardmäßig 29KB lassen sich Streams problemlos übertragen. Der Übertragungspuffer ist per Default 32 KB groß und alles was größer ist, wird gestückelt. Stream.Size liefert dabei nur noch -1 und man muß/kann dann nur noch "blind" einlesen, bis zum Stream-Ende. Im Notfall kann man sich eventuell per Var-Parameter noch die Streamgröße mit übertragen, damit man die Größe prüfen kann. (das hab ich bei uns aber nicht und es läuft dennoch)
Delphi-Quellcode:
function TServerMethods1.GetFile(Filename, Version: string; var StreamSize: Integer): TStream;
Delphi-Quellcode:
procedure TServerMethods1.PutFile(Filename, Version: string; Stream: TStream; StreamSize: Integer);
|
AW: Datasnap REST im Apache, Download einer Datei dauert sehr lange
Zitat:
|
AW: Datasnap REST im Apache, Download einer Datei dauert sehr lange
Weil Viele das Out nicht kennen?
Nja, ich denk oft nicht dran und im Delphi ist es meistens egal (außer daß beim Out hoffentlich der Compiler vorher keine "nicht initialisiert"-Meldung wirft?) Aber hier hast'e schon Recht, im Prinzip ist es natürlich sinnlos, wenn der Parameter bei der Anfrage mit übertragen wird, obwohl man nur die Rückgabe braucht. Und in Verbindung mit Interfaces hatte ich ein paar nette Speicherlecks kennengelernt. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 17:30 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