要监听来自Rest服务器的事件,我需要一个长时间运行的HTTP请求。
我们如何用Delphi做到这一点?
我当前的解决方案有效,但是无法正确解决来自调用方的请求停止。我必须使用Thread.Terminate停止线程。此线程终止会导致不必要的内存泄漏。这就是为什么我正在寻找另一种解决方案。
在没有从服务器接收到新数据的情况下,请求者也必须可以对请求进行交互。我尝试使用BeginExecute / BeginGet进行ALS异步调用,但遇到了同样的问题,即如果没有来自服务器的数据,则无法随时停止请求。
这是我的代码,可以在不同的平台(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;