- Recompilación de todos los paquetes de RO para poner RemObjects_Core_D10 como paquete de runtime/designtime. git-svn-id: https://192.168.0.254/svn/Componentes.Terceros.RemObjects@5 b6239004-a887-0f4b-9937-50029ccdca16
200 lines
5.5 KiB
ObjectPascal
200 lines
5.5 KiB
ObjectPascal
unit ExtendedFileTransferClientDownloadThread;
|
|
|
|
interface
|
|
|
|
uses
|
|
Windows, Messages, SysUtils, Classes, Graphics, Controls,
|
|
uROClient, uROClientIntf, uRORemoteService, uROBinMessage,
|
|
uROIndyTCPChannel, uROIndyHTTPChannel,
|
|
ExtendedFileTransferLibrary_Intf, uROTypes;
|
|
|
|
type
|
|
|
|
{ TROThread }
|
|
TDownloadThread = class(TThread)
|
|
private
|
|
fROMessage: TROBinMessage;
|
|
fROChannel: TROIndyHTTPChannel;
|
|
fRORemoteService: TRORemoteService;
|
|
fOnAbort: TNotifyEvent;
|
|
fOnFinished: TNotifyEvent;
|
|
fOnProgress: TNotifyEvent;
|
|
fOnStartDownload: TNotifyEvent;
|
|
fOnError: TNotifyEvent;
|
|
fDownloadOK: Boolean;
|
|
fCurrentBytePos: Int64;
|
|
fTimeStarted: TDateTime;
|
|
fDownloadDir: string;
|
|
fFileService: IExtendedFileTransferService;
|
|
fErrortext: string;
|
|
fFileName: string;
|
|
fFileSize: Int64;
|
|
fInfoStr: string;
|
|
fMaxConnectionErrors, fChannelErrorscount: Integer;
|
|
|
|
procedure RunDownload;
|
|
procedure ROIndyChannelFailure(Sender: TROTransportChannel;
|
|
anException: Exception; var Retry: Boolean);
|
|
procedure Run;
|
|
|
|
protected
|
|
public
|
|
property DownloadOK: Boolean read fDownloadOK;
|
|
property FileName: string read fFileName;
|
|
property FileSize: Int64 read fFileSize;
|
|
property InfoStr: string read fInfoStr;
|
|
property ErrorText: string read fErrortext;
|
|
property CurrentBytePos: Int64 read fCurrentBytePos;
|
|
property TimeStarted: TDateTime read fTimeStarted;
|
|
constructor Create(aDownloadDir, aFilename: string; aFileSize: Int64;
|
|
aOnStartDownload, aOnProgress, aOnFinished, aOnAbort, aOnError:
|
|
TNotifyEvent);
|
|
destructor Destroy; override;
|
|
|
|
procedure Execute; override;
|
|
end;
|
|
|
|
implementation
|
|
uses ExtendedFileTransferClientMain;
|
|
|
|
{ TROThread }
|
|
|
|
constructor TDownloadThread.Create(aDownloadDir, aFilename: string; aFileSize:
|
|
Int64; aOnStartDownload, aOnProgress, aOnFinished, aOnAbort, aOnError:
|
|
TNotifyEvent);
|
|
begin
|
|
inherited Create(TRUE);
|
|
fDownloadDir := aDownloadDir;
|
|
fFilename := aFilename;
|
|
fFileSize := aFileSize;
|
|
fmaxconnectionerrors := 5; //try 5 times on channel-error
|
|
|
|
fROMessage := TROBinMessage.Create(nil);
|
|
|
|
fROChannel := TROIndyHTTPChannel.Create(nil);
|
|
fROChannel.OnFailure := ROIndyChannelFailure;
|
|
fROChannel.TargetURL := ExtendedFileTransferClientMainForm.ROChannel.TargetURL;
|
|
fRORemoteService := TRORemoteService.Create(nil);
|
|
|
|
fRORemoteService.Channel := fROChannel;
|
|
fRORemoteService.Message := fROMessage;
|
|
fRORemoteService.ServiceName := 'ExtendedFileTransferService';
|
|
fFileService := fRORemoteService as IExtendedFileTransferService;
|
|
|
|
if assigned(aOnAbort) then fOnAbort := aOnAbort;
|
|
if assigned(aOnFinished) then fOnFinished := aOnFinished;
|
|
if assigned(aOnProgress) then fOnProgress := aOnProgress;
|
|
if assigned(aOnStartDownload) then fOnStartDownload := aOnStartDownload;
|
|
if assigned(aOnError) then fOnError := aOnError;
|
|
FreeOnTerminate:=True;
|
|
Resume;
|
|
end;
|
|
|
|
destructor TDownloadThread.Destroy;
|
|
begin
|
|
fFileService := nil;
|
|
FreeAndNil(fROMessage);
|
|
FreeAndNil(fROChannel);
|
|
FreeAndNil(fRORemoteService);
|
|
inherited;
|
|
end;
|
|
|
|
procedure TDownloadThread.Execute;
|
|
begin
|
|
Run;
|
|
end;
|
|
|
|
procedure TDownloadThread.Run;
|
|
begin
|
|
try
|
|
RunDownload;
|
|
finally
|
|
if assigned(fOnFinished) then fOnFinished(Self);
|
|
end;
|
|
end;
|
|
|
|
procedure TDownloadThread.RunDownload;
|
|
var
|
|
NewFile: TMemoryStream;
|
|
Chunk: Binary;
|
|
Sequence: Integer;
|
|
begin
|
|
fDownloadOK := false;
|
|
Chunk := nil;
|
|
try
|
|
if Terminated then begin
|
|
if assigned(fOnAbort) then fOnAbort(Self);
|
|
exit;
|
|
end;
|
|
|
|
NewFile := TMemoryStream.Create;
|
|
try
|
|
fCurrentBytePos := 0;
|
|
Sequence := 1;
|
|
fTimeStarted := Now;
|
|
|
|
fFileService.downloadsequence(fFilename, Sequence, chunk, fFileSize);
|
|
|
|
fInfoStr := DateTimetoStr(fTimeStarted) + ' ' +
|
|
ExtractFileName(fFilename) + ' ' +
|
|
FloatToStrF(fFilesize / 1024, fffixed, 15, 1) + ' KB';
|
|
|
|
if assigned(fOnStartDownload) then
|
|
fOnStartDownload(Self);
|
|
while (chunk <> nil) and (Chunk.Size > 0) do begin
|
|
if Terminated then begin
|
|
FreeAndNil(Chunk);
|
|
if assigned(fOnAbort) then fOnAbort(Self);
|
|
exit;
|
|
end;
|
|
|
|
NewFile.Seek(0, soFromEnd);
|
|
NewFile.CopyFrom(Chunk, Chunk.Size);
|
|
Inc(fCurrentBytePos, Chunk.Size);
|
|
|
|
FreeAndNil(Chunk);
|
|
|
|
if assigned(fOnProgress) then
|
|
fOnProgress(Self);
|
|
Inc(Sequence);
|
|
fFileService.downloadsequence(fFilename, Sequence, chunk, fFileSize);
|
|
end;
|
|
|
|
fDownloadOK := (NewFile.Size = 0) or (fFileSize = CurrentBytePos);
|
|
|
|
if fDownloadOK then begin
|
|
NewFile.SaveToFile(IncludeTrailingPathDelimiter(fDownloadDir) + fFilename);
|
|
fDownloadOK := Fileexists(IncludeTrailingPathDelimiter(fDownloadDir) + fFilename);
|
|
end;
|
|
|
|
finally
|
|
FreeAndNil(Chunk);
|
|
NewFile.Free;
|
|
end;
|
|
|
|
except
|
|
on e: Exception do begin
|
|
fErrorText := e.Message;
|
|
fDownloadOK := false;
|
|
if assigned(fOnError) then fOnError(Self);
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
procedure TDownloadThread.ROIndyChannelFailure(Sender: TROTransportChannel;
|
|
anException: Exception; var Retry: Boolean);
|
|
begin
|
|
if fChannelErrorscount > fMaxConnectionerrors then begin
|
|
fErrorText := anException.Message;
|
|
Self.terminate;
|
|
end
|
|
else begin
|
|
inc(fChannelErrorscount);
|
|
sleep(1000);
|
|
Retry := true;
|
|
end;
|
|
end;
|
|
|
|
end.
|
|
|