Mapping Groups and Connections

In a previous post I Introduced the new Groups feature on WebSocket Servers. This post I will show how to combine the WebSocket Groups with the Client Connections to identify and store the user data in a client connection.

sgcWebSockets library allows you to create your own objects and link to a TsgcWSConnection class, so you can access at any time your custom object when a new message is received, when the client disconnects... Now you can combine the ease of use of the Groups and the Custom Objects to build advanced applications easily.

Authenticate Users

The server will be configured to only accept authenticated user connections, so first enable the Authentication on Server side and then configure the event OnAuthentication to authenticate the connection received by the server. The Users usually will be stored in a database, in this sample the users are hard-coded for simplicity.

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

Find below a sample code, first evaluate if the User/Password are known, if are correct then create a new instance of TsgcUser class were the user data is stored, fill the properties and Assign to the Connection.Data property. This way, you can access to the user data when you receive a message from this user, when disconnects... 

  TsgcUser = class
    FAge: Integer;
    FDepartment: string;
    FPhone: string;
    FUsername: string;
    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;
procedure OnServerAuthentication(Connection: TsgcWSConnection; aUser, 
  aPassword: string; var Authenticated: Boolean);
  oUser: TsgcUser;
  if (aUser = 'user-1') and (aPassword = 'password-1') then
    Authenticated := True;

    oUser := TsgcUser.Create;
    oUser.Username := 'Mark';
    oUser.Phone := '+55431588744134';
    oUser.Department := 'Sales';
    oUser.Age := 22;

    Connection.Data := oUser;
    Authenticated := False;

Once the user is Authenticated, the event OnConnect will be fired, here you can add the user to a Group. In this demo, the Department property of the user will be used as Group Name. You can add a connection to more than 1 group, just call the method Groups.Add as many times as you need.

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

When the client disconnects, the connection class is automatically removed from the Groups property, so there is no need to remove manually because is done automatically. 

Using Events

The Groups property has 2 events to notify every time an user has been added to a group or when it has been removed

OnClientAdded: when a new connection has been added to a group.

OnClientRemoved: when an existing connection has been removed from a group.

You can configure this events before the Server is started. In the following sample, we send a message to all members of the group that a new member has been added or an existing member has disconnected.

Server.Groups.OnClientAdded := OnClientAddedEvent;
Server.Groups.OnClientRemoved := OnClientRemovedEvent;

procedure OnClientAddedEvent(Sender: TObject; const aGroup:
    TsgcWSServerGroupItem; const aConnection: TsgcWSConnection);
  vMessage: string;
  vMessage := TsgcUser(aConnection.Data).Username + ' has logged in.';

procedure TForm16.OnClientRemovedEvent(Sender: TObject; const aGroup:
    TsgcWSServerGroupItem; const aConnection: TsgcWSConnection);
  vMessage: string;
  vMessage := TsgcUser(aConnection.Data).Username + ' has disconnected.';

Sending Messages

You can use the Groups to Broadcast Messages to specific groups, to multiple groups... find below some examples.

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

Find below the sources of the Server and Client application and the compiled binaries for windows. 

3.6 mb
Stay Informed

When you subscribe to the blog, we will send you an e-mail when there are new updates on the site so you wouldn't miss them.

Delphi Server Sent Events (SSE) Client
WebSocket Groups: Channels, Users and more

Related Posts