unit Ws.Server.Module;

interface

uses
  System.SysUtils, System.Classes,
  WebSocket.Manager,
  Ws.DataModel;

type
  TWsServerModule = class(TDataModule)
    procedure DataModuleCreate(Sender: TObject);
    procedure DataModuleDestroy(Sender: TObject);
  private
    FManager: TWebSocketManager;
    FDataModel: TWsDataModel;
    function GetOnClientsChanged: TClientsChangedEvent;
    procedure SetOnClientsChanged(const AValue: TClientsChangedEvent);
  public
    procedure StartWsServer;
    procedure Broadcast(const AMessage: string);
    function GetClientSnapshots: TArray<TConnectedClientSnapshot>;
    property OnClientsChanged: TClientsChangedEvent read GetOnClientsChanged write SetOnClientsChanged;
    procedure DisconnectClient(AConnectionId: string);
    procedure SendMessageToClient(AConnectionId, AText: string);
  end;

var
  WsServerModule: TWsServerModule;

implementation

uses
  Common.Logging;

{$R *.dfm}

procedure TWsServerModule.DataModuleCreate(Sender: TObject);
begin
  FManager := TWebSocketManager.Create;
end;

procedure TWsServerModule.DataModuleDestroy(Sender: TObject);
begin
  FDataModel.Free;
  FDataModel := nil;

  FManager.Free;
  FManager := nil;
end;

procedure TWsServerModule.StartWsServer;
begin
  FManager.Start;
  Logger.Log(1, Format('WebSocket server listening on port %d', [WEBSOCKET_PORT]));

  FDataModel := TWsDataModel.Create(
    procedure(const AMessage: string)
    begin
      Broadcast(AMessage);
    end,
    5000 // notification check interval in ms
  );
  Logger.Log(1, 'WsDataModel started (5 s notification check interval)');
end;

procedure TWsServerModule.Broadcast(const AMessage: string);
begin
  FManager.Broadcast(AMessage);
end;

procedure TWsServerModule.DisconnectClient(AConnectionId: string);
begin
  FManager.DisconnectClient(AConnectionId);
end;

procedure TWsServerModule.SendMessageToClient(AConnectionId, AText: string);
begin
  FManager.SendMessageToClient(AConnectionId, AText);
end;

function TWsServerModule.GetClientSnapshots: TArray<TConnectedClientSnapshot>;
begin
  Result := FManager.GetClientSnapshots;
end;

function TWsServerModule.GetOnClientsChanged: TClientsChangedEvent;
begin
  Result := FManager.OnClientsChanged;
end;

procedure TWsServerModule.SetOnClientsChanged(const AValue: TClientsChangedEvent);
begin
  FManager.OnClientsChanged := AValue;
end;

end.
