123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232 |
- unit webideclient;
- {$mode objfpc}
- interface
- uses
- Classes, SysUtils, js, web;
- type
- TIDEClient = Class;
- TIDEResponseHandler = Procedure (aCode : Integer; aCodeText : String; aPayload : TJSObject) of object;
- { TIDERequest }
- TIDERequest = Class(TObject)
- Private
- FXHR : TJSXMLHttpRequest;
- FOnResponse: TIDEResponseHandler;
- Procedure ProcessResponse;
- procedure DoStateChange;
- Public
- Constructor Create(aMethod, aURl: String; aPayLoad: TJSObject; aOnResponse: TIDEResponseHandler);
- end;
- { TIDEClient }
- TCommandEvent = Procedure (Sender : TObject; aCommands : TJSArray) of object;
- TActionEvent = Procedure (Sender : TObject; aID : Int64; aName : String; aPayload : TJSObject) of object;
- TIDEClient = Class(TComponent)
- private
- FActionID : NativeInt;
- FOnActionResponse: TActionEvent;
- FPollID : NativeInt;
- FCommandPollInterval : Integer;
- FClientID: NativeInt;
- FIDEURL: String;
- FOnCommands: TCommandEvent;
- FLastPoll : TIDERequest;
- FStartPolling : Boolean;
- procedure DoCommandPoll;
- procedure OnActionSent(aCode: Integer; aCodeText: String; aPayload: TJSObject);
- procedure OnClientRegistered(aCode: Integer; aCodeText: String; aPayload: TJSObject);
- procedure OnCommandsReceived(aCode: Integer; aCodeText: String; aPayload: TJSObject);
- Public
- Constructor Create(aOwner : TComponent); override;
- Procedure RegisterClient;
- Procedure UnRegisterClient;
- Procedure StartCommandPolling;
- Procedure StopCommandPolling;
- Function GetNextID : NativeInt;
- procedure SendAction(Const aName : String; aPayLoad : TJSObject);
- Property IDEURL : String read FIDEURL Write FIDEURL;
- Property ClientID : Int64 read FClientID Write FClientID;
- Property CommandPollInterval : Integer Read FCommandPollInterval Write FCommandPollInterval;
- Property OnCommands : TCommandEvent Read FOnCommands Write FOnCommands;
- Property OnActionResponse : TActionEvent Read FOnActionResponse Write FOnActionResponse;
- end;
- implementation
- { TIDEClient }
- procedure TIDEClient.DoCommandPoll;
- begin
- if Not Assigned(FLastPoll) then
- FLastPoll:=TIDERequest.Create('Get',IDEURL+'Command/'+IntToStr(ClientID)+'/',Nil,@OnCommandsReceived);
- end;
- procedure TIDEClient.OnActionSent(aCode: Integer; aCodeText: String; aPayload: TJSObject);
- Var
- aID : NativeInt;
- aName : string;
- aActionPayload : TJSObject;
- begin
- if (aCode div 100)=2 then
- begin
- aID:=NativeInt(aPayLoad['id']);
- aName:=String(aPayLoad['name']);
- aActionPayLoad:=TJSObject(aPayLoad['payload']);
- If Assigned(OnActionResponse) then
- OnActionResponse(Self,aID,aName,aActionPayload);
- end;
- end;
- procedure TIDEClient.OnClientRegistered(aCode: Integer; aCodeText: String; aPayload: TJSObject);
- begin
- if (aCode div 100)=2 then
- begin
- FClientID:=NativeInt(aPayload['id']);
- if FStartPolling then
- StartCommandPolling;
- end
- else
- FClientID:=0;
- end;
- procedure TIDEClient.OnCommandsReceived(aCode: Integer; aCodeText: String; aPayload: TJSObject);
- Var
- A: TJSArray;
- begin
- FLastPoll:=Nil;
- if (aCode div 100)<>2 then
- exit;
- if Assigned(aPayload) and isArray(aPayload['commands']) then
- begin
- A:=TJSArray(aPayload['commands']);
- if (A.Length>0) then
- OnCommands(Self,A);
- end;
- end;
- constructor TIDEClient.Create(aOwner: TComponent);
- begin
- Inherited;
- FLastPoll:=Nil;
- IDEURL:='http://'+Window.location.hostname+':'+Window.location.port+'/IDE/';
- end;
- procedure TIDEClient.RegisterClient;
- Var
- P : TJSObject;
- Req : TIDERequest;
- begin
- P:=New(['url',window.locationString]);
- req:=TIDERequest.Create('POST',IDEURL+'Client',P,@OnClientRegistered);
- end;
- procedure TIDEClient.UnRegisterClient;
- Var
- Req : TIDERequest;
- begin
- Req:=TIDERequest.Create('DELETE',IDEURL+'Client/'+IntToStr(ClientID),Nil,@OnClientRegistered);
- end;
- procedure TIDEClient.StartCommandPolling;
- begin
- if ClientID<>0 then
- FPollID:=Window.setInterval(@DoCommandPoll,FCommandPollInterval)
- else
- FStartPolling:=True;
- end;
- procedure TIDEClient.StopCommandPolling;
- begin
- FStartPolling:=False;
- if (FPollID>0) then
- Window.clearInterval(FPollID);
- end;
- function TIDEClient.GetNextID: NativeInt;
- begin
- Inc(FActionID);
- Result:=FActionID;
- end;
- procedure TIDEClient.SendAction(const aName: String; aPayLoad: TJSObject);
- Var
- aAction : TJSObject;
- aID : NativeInt;
- req: TIDERequest;
- begin
- aID:=GetNextID;
- aAction:=New(['id',aID,
- 'name',aName,
- 'payload',aPayLoad]);
- req:=TIDERequest.Create('POST',IDEURL+'Action/'+IntToStr(ClientID)+'/'+IntToStr(aID),aAction,@OnActionSent);
- end;
- { TIDERequest }
- procedure TIDERequest.ProcessResponse;
- var
- P : TJSObject;
- begin
- if ((FXHR.Status div 100)=2) and (FXHR.ResponseHeaders['Content-Type']='application/json') then
- P:=TJSJSON.parseObject(FXHR.responseText)
- else
- P:=Nil;
- if Assigned(FOnResponse) then
- FOnResponse(FXHR.Status,FXHR.StatusText,P);
- end;
- procedure TIDERequest.DoStateChange;
- begin
- case FXHR.readyState of
- TJSXMLHttpRequest.DONE :
- begin
- if Assigned(FOnResponse) then
- ProcessResponse;
- Free;
- end;
- end;
- end;
- constructor TIDERequest.Create(aMethod, aURl: String; aPayLoad: TJSObject; aOnResponse: TIDEResponseHandler);
- Var
- S : String;
- begin
- FOnResponse:=aOnResponse;
- FXHR:=TJSXMLHttpRequest.New;
- FXHR.open(aMethod,aURL);
- if assigned(aPayload) then
- S:=TJSJSON.Stringify(aPayload)
- else
- S:='';
- FXHR.setRequestHeader('Content-Type','application/json');
- FXHR.onreadystatechange:=@DoStateChange;
- FXHR.send(S);
- end;
- end.
|