⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 rtcdatacli.pas

📁 Delphi快速开发Web Server
💻 PAS
📖 第 1 页 / 共 5 页
字号:
      Leave HyperThreading as FALSE to use this component "the stadard way" (for example,
      when you're writing a client application where requests are posted from the main thread
      or if you are creating a separate component for every thread that needs it). }
    property HyperThreading:boolean read FHyperThreading write FHyperThreading default False;

    { Set this property to a value other than 0 (zero) if you want the DataRequest to
      auto-repost any request up to "AutoRepost" times, in case the connection gets lost
      while sending data to server or receiving data from server.
      AutoRepost = -1 means that request should be reposted infinitely. }
    property AutoRepost:integer read FAutoRepost write FAutoRepost default 0;

    { This event will be called when DataClient component is
      ready to start sending the request out.
      @html(<br><br>)
      If the request is already in memory (not a large file on disk),
      send it out using Sender's WriteHeader and/or Write methods.
      If the request is too large to be sent out at once (maybe a big file
      on disk), you should at least send the Request Header out in this event.
      @html(<br><br>)
      If you DO NOT call Write and/or WriteHeader from this event,
      then this Request will be skipped by the DataClient. }
    property OnBeginRequest:TRtcNotifyEvent read FOnBeginRequest write FOnBeginRequest;
    { This event will be called after each DataReceived event for this request
      and can be used to access info prepared by the OnDataReceived event. }
    property OnResponseData:TRtcNotifyEvent read FOnResponseData write FOnResponseData;
    { This event will be called after the last DataReceived event for this request,
      read after the request has been sent out and a complete response was received (Response.Done). }
    property OnResponseDone:TRtcNotifyEvent read FOnResponseDone write FOnResponseDone;
    { This event will be called after ConnectLost, ConnectFail and ConnectError events if request was not marked for reposting.

      If you want to re-post the request, you should call Request.Repost from
      this event, or the Request will NOT be reposted and OnResponseAbort
      event will be trigered. You can also use the AutoRepost property to tell the
      component to repost requests automaticaly (for a specified number of times or unlimited). }
    property OnRepostCheck:TRtcNotifyEvent read FOnRepostCheck write FOnRepostCheck;
    { This event will be called after the OnRepostCheck event if request was not marked for reposting. }
    property OnResponseAbort:TRtcNotifyEvent read FOnResponseAbort write FOnResponseAbort;

    { This event will be called after the response has been rejected by calling Response.Reject }
    property OnResponseReject:TRtcNotifyEvent read FOnResponseReject write FOnResponseReject;

    { This event will be called after a new Session has been opened. }
    property OnSessionOpen:TRtcNotifyEvent read FOnSessionOpen write FOnSessionOpen;
    { This event will be called before an existing Session is about to close. }
    property OnSessionClose:TRtcNotifyEvent read FOnSessionClose write FOnSessionClose;

    { This event will be mapped as TRtcDataClient.OnDataReceived event
      to the assigned DataClient component and called for all DataReceived
      events until the request is processed in full, skipped or rejected. }
    property OnDataReceived:TRtcNotifyEvent read FOnDataReceived write FOnDataReceived;

    { This event will be mapped as @Link(TRtcConnection.OnDataOut) event
      to the assigned DataClient component and called for all DataOut
      events until the request is processed in full, skipped or rejected. }
    property OnDataOut:TRtcNotifyEvent read FOnDataOut write FOnDataOut;

    { This event will be mapped as @Link(TRtcConnection.OnDataIn) event
      to the assigned DataClient component and called for all DataIn
      events until the request is processed in full, skipped or rejected. }
    property OnDataIn:TRtcNotifyEvent read FOnDataIn write FOnDataIn;

    { This event will be mapped as @Link(TRtcConnection.OnDataSent) event
      to the assigned DataClient component and called for all DataSent
      events until the request is processed in full, skipped or rejected. }
    property OnDataSent:TRtcNotifyEvent read FOnDataSent write FOnDataSent;

    { This event will be mapped as @Link(TRtcConnection.OnReadyToSend) event
      to the assigned DataClient component and called for all ReadyToSend
      events until the request is processed in full, skipped or rejected. }
    property OnReadyToSend:TRtcNotifyEvent read FOnReadyToSend write FOnReadyToSend;

    { This event will be mapped as @Link(TRtcClient.OnConnectLost) event
      to the assigned DataClient component and called if your connection gets
      closed while you are processing your request (sending or receiving data).
      @html(<br><br>)

      If you want to re-send the request, you can call Request.Repost from this event,
      or use the OnRepostCheck or OnResponseAborted events to do so. }
    property OnConnectLost:TRtcNotifyEvent read FOnConnectLost write FOnConnectLost;
    end;

implementation

type
  { @abstract(DataRequest Job)

    This Job is used by TRtcDataClient to post a signal to start a request

    @exclude }
  TRtcStartRequestJob=class(TRtcJob)
    Client:TRtcDataClient;

    procedure Kill; override;
    procedure Run(Thr:TRtcThread); override;
    end;

{ TRtcDataClientLinkList }

constructor TRtcDataClientLinkList.Create;
  begin
  inherited;
  FList:=TList.Create;
  end;

destructor TRtcDataClientLinkList.Destroy;
  begin
  FList.Free;
  inherited;
  end;

procedure TRtcDataClientLinkList.Add(Value: TRtcAbsDataClientLink);
  var
    idx:integer;
  begin
  idx:=FList.IndexOf(Value);
  if idx<0 then
    FList.Add(Value);
  end;

function TRtcDataClientLinkList.Count: integer;
  begin
  Result:=FList.Count;
  end;

function TRtcDataClientLinkList.Get(index:integer): TRtcAbsDataClientLink;
  begin
  if (index>=0) and (index<FList.Count) then
    Result:=TRtcAbsDataClientLink(FList.Items[index])
  else
    Result:=nil;
  end;

procedure TRtcDataClientLinkList.Remove(Value: TRtcAbsDataClientLink);
  var
    idx:integer;
  begin
  idx:=FList.IndexOf(Value);
  if idx>=0 then
    FList.Delete(idx);
  end;

procedure TRtcDataClientLinkList.RemoveAll;
  begin
  FList.Clear;
  end;

{ TRtcDataClient }

constructor TRtcDataClient.Create(AOwner: TComponent);
  begin
  inherited Create(AOwner);

  FMyRequest:=TRtcClientRequest.Create;
  FMyResponse:=TRtcClientResponse.Create;

  FRequest:=FMyRequest;
  FResponse:=FMyResponse;

  FCS:=TRtcCritSec.Create;
  FSession:=TRtcClientSession.Create;
  FSession.FCon:=self;
  FMayInsertRequest:=False;
  FRequestInserted:=False;

  FDataClientLinks:=TRtcDataClientLinkList.Create;

  FRequestList:=TList.Create;
  FActiveRequest:=nil;
  FIdle:=True;
  FRequestSkipped:=0;
  end;

destructor TRtcDataClient.Destroy;
  begin
  RemoveAllDataClientLinks;
  FDataClientLinks.Free;
  FDataClientLinks:=nil;

  if assigned(FRequestList) then
    begin
    RemoveAllRequests;
    RemoveRequest;
    FRequestList.Free;
    FRequestList:=nil;
    end;

  FActiveRequest:=nil;
  FIdle:=True;

  FMyRequest.Free; FRequest:=nil;
  FMyResponse.Free; FResponse:=nil;

  FSession.Free;
  FCS.Free;
  inherited;
  end;

procedure TRtcDataClient.CallConnect;
  begin
  inherited;
  if MultiThreaded then
    PostStartRequest
  else
    StartRequest;
  end;

procedure TRtcDataClient.CallReadyToSend;
  begin
  if assigned(FActiveRequest) then
    begin
    FActiveRequest.Call_ReadyToSend(self);
    Flush;
    CheckRequestWork;
    end
  else
    inherited;
  end;

procedure TRtcDataClient.CallDataSent;
  begin
  if assigned(FActiveRequest) then
    begin
    FActiveRequest.Call_DataSent(self);
    Flush;
    CheckRequestWork;
    end
  else
    inherited;
  end;

procedure TRtcDataClient.CallDataOut;
  begin
  if assigned(FActiveRequest) then
    FActiveRequest.Call_DataOut(self);

  inherited;

  Flush;
  end;

procedure TRtcDataClient.CallDataIn;
  begin
  if assigned(FActiveRequest) then
    FActiveRequest.Call_DataIn(self);

  inherited;
  end;

procedure TRtcDataClient.CallDataReceived;
  begin
  if assigned(FActiveRequest) then
    begin
    FActiveRequest.Call_DataReceived(self);
    Flush;
    if CheckRequestWork then Exit;

    FActiveRequest.Call_ResponseData(self);
    Flush;
    if CheckRequestWork then Exit;

    if assigned(Request.OnData) then
      begin
      Request.OnData(self);
      Flush;
      if CheckRequestWork then Exit;
      end;

    if Response.Done then
      begin
      FActiveRequest.Call_ResponseDone(self);
      if CheckRequestWork then Exit;

      if assigned(Request.OnDone) then
        Request.OnDone(self);
      if CheckRequestWork then Exit;

      RemoveRequest;
      if MultiThreaded then
        PostStartRequest
      else
        StartRequest;
      end;
    end
  else
    inherited;
  end;

procedure TRtcDataClient.CallConnectLost;
  begin
  if assigned(FActiveRequest) then
    begin
    FActiveRequest.Call_ConnectLost(self);
    if not Response.Done and not Request.Reposting then
      begin
      FActiveRequest.Call_RepostCheck(self);
      if not Response.Done and not Request.Reposting then
        begin
        FActiveRequest.Call_ResponseAbort(self);
        if assigned(Request.OnAbort) then
          if not Request.Reposting then
            Request.OnAbort(self);
        end;
      end;

    inherited;

    if Request.Skipped then
      RemoveRequest
    else if Response.Rejected then
      begin
      FActiveRequest.Call_ResponseReject(self);
      if assigned(Request.OnReject) then
        Request.OnReject(self);
      RemoveRequest;
      end
    else if Request.Reposting then
      begin
      Request.Reposting:=False;
      Response.Clear;
      end
    else if Response.Done then
      RemoveRequest
    else
      begin
      RemoveRequest;
      // We will skip all remaining requests
      CancelRequests;
      end;

    // This will remove all skipped requests
    PrepareNextRequest;
    end
  else
    inherited;
  end;

procedure TRtcDataClient.CallConnectFail;
  begin
  PrepareNextRequest;

  if assigned(FActiveRequest) then
    begin
    FActiveRequest.Call_RepostCheck(self);
    if not Response.Done and not Request.Reposting then
      begin
      FActiveRequest.Call_ResponseAbort(self);
      if assigned(Request.OnAbort) then
        if not Request.Reposting then
          Request.OnAbort(self);
      end;

    inherited;

    if Request.Skipped then
      RemoveRequest
    else if Response.Rejected then
      begin
      FActiveRequest.Call_ResponseReject(self);
      if assigned(Request.OnReject) then
        Request.OnReject(self);
      RemoveRequest;
      end
    else if Request.Reposting then
      begin
      Request.Reposting:=False;
      Response.Clear;
      end
    else if Response.Done then
      RemoveRequest
    else
      begin
      RemoveRequest;
      // We will skip all remaining requests
      CancelRequests;
      end;

    // This will remove all skipped requests
    PrepareNextRequest;
    end
  else
    inherited;
  end;

procedure TRtcDataClient.CallConnectError(E:Exception);
  begin
  PrepareNextRequest;

  if assigned(FActiveRequest) then
    begin
    FActiveRequest.Call_RepostCheck(self);
    if not Response.Done and not Request.Reposting then
      begin
      FActiveRequest.Call_ResponseAbort(self);
      if assigned(Request.OnAbort) then
        if not Request.Reposting then
          Request.OnAbort(self);
      end;

    inherited;

    if Request.Skipped then
      RemoveRequest
    else if Response.Rejected then
      begin
      FActiveRequest.Call_ResponseReject(self);
      if assigned(Request.OnReject) then
        Request.OnReject(self);
      RemoveRequest;
      end
    else if Request.Reposting then
      begin
      Request.Reposting:=False;
      Response.Clear;
      end
    else if Response.Done then
      RemoveRequest
    else
      begin

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -