En un post anterior presenté la nueva característica de Grupos en los servidores WebSocket. En este post mostraré cómo combinar los grupos WebSocket con las conexiones de cliente para identificar y almacenar los datos del usuario en una conexión cliente.
La biblioteca sgcWebSockets te permite crear tus propios objetos y enlazarlos a una clase TsgcWSConnection, así puedes acceder en cualquier momento a tu objeto personalizado cuando se recibe un nuevo mensaje, cuando el cliente se desconecta... Ahora puedes combinar la facilidad de uso de los Grupos y los Objetos personalizados para construir aplicaciones avanzadas fácilmente.
Autenticar usuarios
El servidor se configurará para aceptar solo conexiones de usuario autenticadas, así que primero activa la autenticación en el lado del servidor y luego configura el evento OnAuthentication para autenticar la conexión recibida por el servidor. Los usuarios normalmente se almacenarán en una base de datos; en esta muestra los usuarios están hardcodeados por simplicidad.
Server.Authentication.Enabled := True; Server.Authentication.Basic.Enabled := True;
A continuación encontrarás un código de ejemplo: primero evalúa si el usuario/contraseña son conocidos; si son correctos, crea una nueva instancia de la clase TsgcUser donde se almacenan los datos del usuario, rellena las propiedades y asigna a la propiedad Connection.Data. De esta forma, puedes acceder a los datos del usuario cuando recibes un mensaje de este usuario, cuando se desconecta...
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 vez que el usuario está autenticado, el evento OnConnect se lanzará; aquí puedes añadir el usuario a un grupo. En esta demo, la propiedad Department del usuario se usará como nombre del grupo. Puedes añadir una conexión a más de 1 grupo; basta con llamar al método Groups.Add tantas veces como necesites.
procedure OnServerConnect(Connection: TsgcWSConnection); begin Server.Groups.Add(TsgcUser(Connection.Data).Department, Connection); end;
Cuando el cliente se desconecta, la clase connection se elimina automáticamente de la propiedad Groups, así que no es necesario eliminar manualmente porque se hace automáticamente.
Usando eventos
La propiedad Groups tiene 2 eventos para notificar cada vez que un usuario se ha añadido a un grupo o cuando se ha eliminado
OnClientAdded: cuando una nueva conexión se ha añadido a un grupo.
OnClientRemoved: cuando una conexión existente se ha eliminado de un grupo.
Puedes configurar estos eventos antes de que se inicie el servidor. En la siguiente muestra, enviamos un mensaje a todos los miembros del grupo de que se ha añadido un nuevo miembro o un miembro existente se ha desconectado.
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;
Envío de mensajes
Puedes usar los grupos para hacer broadcast de mensajes a grupos específicos, a múltiples grupos... a continuación encontrarás algunos ejemplos.
// 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.');
A continuación encontrarás las fuentes de la aplicación servidor y cliente y los binarios compilados para windows.
