【问题标题】:Delphi: Use TidHTTPServer for transfer file and monitoring byte send for single requestDelphi:使用 TidHTTPServer 传输文件并监控单个请求的字节发送
【发布时间】:2014-11-06 19:50:51
【问题描述】:

使用TIdHTTPServer (Indy 10.6),如何跟踪每个请求(关闭连接时)发送到客户端(用户浏览器)的字节数?

procedure onCommandGet(AContext: TIdContext; ARequestInfo: TIdHTTPRequestInfo; AResponseInfo: TIdHTTPResponseInfo;
begin
    AResponseInfo.ContentStream := TFileStream.Create('C:/HugeFile.zip', fmOpenRead or fmShareCompat);
    AResponseInfo.ContentLength := AResponseInfo.ContentStream.Size;
    AResponseInfo.WriteHeader;
    AResponseInfo.WriteContent;
    AResponseInfo.ContentStream.Free;
    AResponseInfo.ContentStream := nil;
end;

例如,在日志文件中:

2014-11-06 20:32:00 - IPAddress 84.XXX.XXX.XXX 下载 1000000 字节 (100%) 2014-11-05 16:05:00 - IPAddress 72.XXX.XXX.XXX 下载 500000 字节 (50%)

【问题讨论】:

  • 您使用的是什么 Indy 版本?下载文件的 50% 代表什么?您是否要记录增量进度(例如,IPAddress 72.xxx.xxx.xxx 下载 100000 字节 (10%)、IPAddress 72.xxx.xxx.xxx 下载 150000 字节 (15%) 等)?
  • 您的代码可以缩短:只需要AResponseInfo.ContentStream := TFileStream.Create(...)。 Indy 配置并写入响应,并释放流。
  • @KenWhite What Indy version are you using? 10.6; What would downloading 50% of a file represent? 客户端在下载量达到 50% 时关闭连接;

标签: delphi indy idhttp


【解决方案1】:

如果您只想在传输结束时输出一个日志,说明发送了多少字节,您可以从TFileStream 派生一个新类并覆盖其析构函数以输出一条日志消息,显示流的当前Position相对于它的Size。您需要记录的任何其他信息都可以传递给构造函数并保存,以便析构函数可以使用它。

例如:

type
  TMyFileStream = class(TFileStream)
  private
    FContext: TIdContext;
  public
    constructor Create(const AFileName: string; AContext: TIdContext);
    destructor Destroy; override;
  end;

constructor TMyFileStream.Create(const AFileName: string; AContext: TIdContext);
begin
  inherited Create(AFileName, fmOpenRead or fmShareCompat);
  FContext := AContext;
end;

destructor TMyFileStream.Destroy;
var
  LPos, LSize: Int64;
  LPercent: Integer;
begin
  LPos := Position;
  LSize := Size;
  if LSize <> 0 then
    LPercent := (LPosition * 100) div LSize
  else
    LPercent := 100;
  MyLogFile.WriteLine(Format('%s IPAddress %s download %d Bytes (%d%%)', [FormatDateTime('YYYY-MM-DD HH:NN:SS', Now), AContext.Binding.PeerIP, LPos, LPercent]);
  inherited;
end;

procedure onCommandGet(AContext: TIdContext; ARequestInfo: TIdHTTPRequestInfo; AResponseInfo: TIdHTTPResponseInfo;
begin
  AResponseInfo.ContentStream := TMyFileStream.Create('C:/HugeFile.zip', AContext);
end;

【讨论】:

  • 使用 OnCommandGet 跟踪下载我发现:AContext.Connection.OnWorkBegin := OnWorkBegin;AContext.Connection.OnWork := OnWork;AContext.Connection.OnWorkEnd := OnWorkEnd;OnWork.. 事件有一个 AWorkMode 参数来告诉你数据流向哪个方向 - wmWrite(下载)或wmRead(上传)和AWorkCountMax上传或下载的字节数
  • 或者我可以使用 onWorkBegin、onWork、onWorkEnd??
  • 如果您在传输过程中需要实时统计数据,可以。
猜你喜欢
  • 2013-01-11
  • 2012-10-12
  • 2014-08-29
  • 1970-01-01
  • 1970-01-01
  • 2016-06-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多