unit ClientForm;
interface
uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, ChannelID,
  DSClientRest, DSClientMetadata, DSProxyDelphiRest, DBXJSON, IndyPeerImpl;

type
  TFormClient = class(TForm)
    CallbackID: TLabel;
    btnRegisterCallback: TButton;
    btnUnregisterCallback: TButton;
    Memo1: TMemo;
    DSRestConnection1: TDSRestConnection;
    btnALARM: TButton;
    procedure FormCreate(Sender: TObject);
    procedure btnRegisterCallbackClick(Sender: TObject);
    procedure btnUnregisterCallbackClick(Sender: TObject);
    procedure btnALARMClick(Sender: TObject);
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
  private
    { Private declarations }
    procedure QueueLogValue(const AValue: string);
  protected
    { Protected declarations }
    ChannelManager: TDSRestClientChannel;
  public
    { Public declarations }
  end;

var
  FormClient: TFormClient;

implementation
uses
  ComObj;

{$R *.dfm}

procedure TFormClient.FormCreate(Sender: TObject);
begin
  CallbackID.Caption := CreateClassID
end;

procedure TFormClient.QueueLogValue(const AValue: string);
begin
  TThread.Queue(nil,
    procedure
    begin
      Memo1.Lines.Add(AValue)
    end)
end;

procedure TFormClient.btnRegisterCallbackClick(Sender: TObject);
var
  callback: TDSRestClientCallback;
begin
  ChannelManager := TDSRestClientChannel.Create(CallbackID.Caption, ChannelName, DSRestConnection1);
  callback := TDSRestClientCallback.Create(ChannelManager, CallbackID.Caption,
    function(AValue: TJSONValue; ADataType: string): boolean
    begin
      // Current thread is not main, so use queue to avoid SendMessage deadlock.
      QueueLogValue(AValue.ToString);
      Result := True
    end);
  ChannelManager.Connect(callback);
  if ChannelManager.Connected then
  begin
    ChannelManager.RegisterCallback(callback);
    btnRegisterCallback.Enabled := False
  end
end;

procedure TFormClient.btnUnregisterCallbackClick(Sender: TObject);
begin
  FreeAndNil(ChannelManager);
  btnRegisterCallback.Enabled := True
end;

procedure TFormClient.btnALARMClick(Sender: TObject);
begin
  ChannelBroadCast(ChannelManager);
end;

procedure TFormClient.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  FreeAndNil(ChannelManager)
end;

end.
