Mappare gruppi e connessioni

· Funzionalità

In un post precedente ho introdotto la nuova funzionalità Groups sui server WebSocket. In questo post mostrerò come combinare i Groups WebSocket con le connessioni client per identificare e memorizzare i dati utente in una connessione client.

La libreria sgcWebSockets ti permette di creare i tuoi oggetti e collegarli a una classe TsgcWSConnection, così puoi accedere in qualsiasi momento al tuo oggetto personalizzato quando viene ricevuto un nuovo messaggio, quando il client si disconnette... Ora puoi combinare la facilità d'uso dei Groups e degli Custom Objects per costruire facilmente applicazioni avanzate.

Autenticazione degli utenti

Il server sarà configurato per accettare solo connessioni di utenti autenticati, quindi prima abilita l'autenticazione lato server e poi configura l'evento OnAuthentication per autenticare la connessione ricevuta dal server. Gli utenti di solito saranno memorizzati in un database, in questo esempio gli utenti sono scritti hard-coded per semplicità.

Server.Authentication.Enabled := True;
Server.Authentication.Basic.Enabled := True;

Di seguito un codice di esempio, prima valuta se User/Password sono conosciuti, se sono corretti crea una nuova istanza della classe TsgcUser dove sono memorizzati i dati utente, compila le proprietà e assegnala alla proprietà Connection.Data. In questo modo, puoi accedere ai dati utente quando ricevi un messaggio da questo utente, quando si disconnette... 

type
  TsgcUser = class
  private
    FAge: Integer;
    FDepartment: string;
    FPhone: string;
    FUsername: string;
  public
    property Username: string read FUsername write FUsername;
    property Department: string read FDepartment write FDepartment;
    property Phone: string read FPhone write FPhone;
    property Age: Integer read FAge write FAge;
  end;
procedure OnServerAuthentication(Connection: TsgcWSConnection; aUser,
  aPassword: string; var Authenticated: Boolean);
var
  oUser: TsgcUser;
begin
  if (aUser = 'user-1') and (aPassword = 'password-1') then
  begin
    Authenticated := True;
    oUser := TsgcUser.Create;
    oUser.Username := 'Mark';
    oUser.Phone := '+55431588744134';
    oUser.Department := 'Sales';
    oUser.Age := 22;
    Connection.Data := oUser;
  end
  else
    Authenticated := False;
end;

Una volta che l'utente è autenticato, verrà generato l'evento OnConnect, qui puoi aggiungere l'utente a un gruppo. In questa demo, la proprietà Department dell'utente verrà usata come nome del gruppo. Puoi aggiungere una connessione a più di 1 gruppo, basta chiamare il metodo Groups.Add tante volte quante ne hai bisogno.

procedure OnServerConnect(Connection: TsgcWSConnection);
begin
  Server.Groups.Add(TsgcUser(Connection.Data).Department, Connection);
end;

Quando il client si disconnette, la classe della connessione viene rimossa automaticamente dalla proprietà Groups, quindi non c'è bisogno di rimuoverla manualmente perché viene fatto automaticamente. 

Usare gli eventi

La proprietà Groups ha 2 eventi per notificare ogni volta che un utente è stato aggiunto a un gruppo o quando è stato rimosso.

OnClientAdded: quando una nuova connessione è stata aggiunta a un gruppo.

OnClientRemoved: quando una connessione esistente è stata rimossa da un gruppo.

Puoi configurare questi eventi prima che il server venga avviato. Nell'esempio seguente, inviamo un messaggio a tutti i membri del gruppo per comunicare che un nuovo membro è stato aggiunto o che un membro esistente si è disconnesso.

Server.Groups.OnClientAdded := OnClientAddedEvent;
Server.Groups.OnClientRemoved := OnClientRemovedEvent;
procedure OnClientAddedEvent(Sender: TObject; const aGroup:
    TsgcWSServerGroupItem; const aConnection: TsgcWSConnection);
var
  vMessage: string;
begin
  vMessage := TsgcUser(aConnection.Data).Username + ' has logged in.';
  aGroup.BroadCast(vMessage);
end;
procedure TForm16.OnClientRemovedEvent(Sender: TObject; const aGroup:
    TsgcWSServerGroupItem; const aConnection: TsgcWSConnection);
var
  vMessage: string;
begin
  vMessage := TsgcUser(aConnection.Data).Username + ' has disconnected.';
  aGroup.BroadCast(vMessage);
end;

Invio di messaggi

Puoi usare i Groups per fare broadcast di messaggi a gruppi specifici, a più gruppi... vedi sotto alcuni esempi.

// All members
Server.Groups.Broadcast('*', 'Hello All Members.');
// Only group "admin"
Server.Groups.Broadcast('admin', 'Hello Admin Members.');
// All sales groups (sales/asi, sales/europe, sales/america...)
Server.Groups.Broadcast('sales/*', 'Hello Sales Members.');
// Only group "accounting" (must exists!!!)
Server.Groups.Group['accounting'].Broadcast('Hello Accounting Members.');

Di seguito i sorgenti delle applicazioni Server e Client e i binari compilati per Windows.