Mapping Groups and Connections

· Fonctionnalités

Dans un précédent article, j'ai présenté la nouvelle fonctionnalité Groups des serveurs WebSocket. Dans cet article, je vais montrer comment combiner les Groups WebSocket avec les connexions clientes pour identifier et stocker les données utilisateur dans une connexion cliente.

La bibliothèque sgcWebSockets te permet de créer tes propres objets et de les lier à une classe TsgcWSConnection, ce qui te donne accès à ton objet personnalisé à tout moment : lors de la réception d'un nouveau message, à la déconnexion du client, etc. Tu peux désormais combiner la facilité d'utilisation des Groups et des objets personnalisés pour construire facilement des applications avancées.

Authentifier les utilisateurs

Le serveur sera configuré pour n'accepter que les connexions d'utilisateurs authentifiés. Il faut donc d'abord activer l'authentification côté serveur, puis configurer l'événement OnAuthentication pour authentifier la connexion reçue par le serveur. Les utilisateurs sont généralement stockés dans une base de données ; dans cet exemple, ils sont codés en dur pour simplifier.

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

Voici un exemple de code : d'abord il évalue si l'utilisateur/mot de passe sont connus ; s'ils sont corrects, il crée une nouvelle instance de la classe TsgcUser dans laquelle sont stockées les données utilisateur, remplit les propriétés et l'assigne à la propriété Connection.Data. Tu peux ainsi accéder aux données utilisateur lors de la réception d'un message de cet utilisateur, lors de sa déconnexion, etc. 

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;

Une fois l'utilisateur authentifié, l'événement OnConnect est déclenché : tu peux y ajouter l'utilisateur à un Group. Dans cette démo, la propriété Department de l'utilisateur sert de nom de Group. Tu peux ajouter une connexion à plus d'un group : appelle simplement la méthode Groups.Add autant de fois que nécessaire.

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

Quand le client se déconnecte, la classe connexion est automatiquement retirée de la propriété Groups : pas besoin de la retirer manuellement. 

Utilisation des événements

La propriété Groups a 2 événements pour notifier chaque ajout ou suppression d'utilisateur d'un group.

OnClientAdded : quand une nouvelle connexion a été ajoutée à un group.

OnClientRemoved : quand une connexion existante a été retirée d'un group.

Tu peux configurer ces événements avant que le serveur ne soit démarré. Dans l'exemple suivant, on envoie un message à tous les membres du group quand un nouveau membre a été ajouté ou qu'un membre existant s'est déconnecté.

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;

Envoi de messages

Tu peux utiliser les Groups pour diffuser des messages à des groups spécifiques, à plusieurs groups, etc. Voici quelques exemples.

// 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.');

Tu trouveras ci-dessous les sources de l'application serveur et cliente et les binaires compilés pour Windows.