1

要监听来自 Rest 服务器的事件,我需要一个长时间运行的 HTTP 请求。

我们如何用 Delphi 做到这一点?

我当前的解决方案有效,但调用方的请求停止没有得到正确解决。我必须使用 Thread.Terminate 来停止线程。此线程终止会导致不必要的内存泄漏。这就是为什么我正在寻找另一种解决方案。

在没有从服务器接收到新数据的情况下,调用者也必须可以中断请求。我尝试使用 BeginExecute/BeginGet 进行异步调用,但我看到了同样的问题,即如果没有来自服务器的数据,请求就无法随时停止。

这是我的代码,它最终可以在不同的平台(Win/OSX/Android)上工作:

type
  TMyRestAPI = class
  private
    fClient: THTTPClient;
    fStream: TMemoryStream;
    fReadPos: Int64;
    fOnReceiveData: procedure(const data: string) of object;
    procedure OnRecData(const Sender: TObject; AContentLength: Int64;
      AReadCount: Int64; var Abort: Boolean);
  public
    procedure StartRequest(const URL: string);
    procedure StopRequest;
  end;

procedure TMyRestAPI.StartRequest(const URL: string);
begin
  fClient := THTTPClient.Create;
  fClient.HandleRedirects := true;
  fClient.Accept := 'text/event-stream';
  fClient.OnReceiveData := OnRecData;
  fStream := TMemoryStream.Create;
  fReadPos := 0;
  fThread := TThread.CreateAnonymousThread(
    procedure
    begin
      fClient.Get(URL, fStream);
    end);
  fThread.Start;
end;

procedure TMyRestAPI.OnRecData(const Sender: TObject; AContentLength: Int64;
  AReadCount: Int64; var Abort: Boolean);
var
  ss: TStringStream;
  resp: string;
begin
  ss := TStringStream.Create;
  try
    fStream.Position := readPos;
    ss.CopyFrom(fStream, AReadCount - fReadPos);
    fOnReceiveData(ss.DataString);
    fReadPos := AReadCount;
  finally
    ss.Free;
  end;
end;

procedure TMyRestAPI.StopRequest;
begin
  fThread.Terminate;
  fClient.Free;
  fStream.Free;
end;
4

0 回答 0