在上一篇文章中,我介绍了 WebSocket 服务器新增的分组功能。本文将展示如何将 WebSocket 分组与客户端连接相结合,以便在客户端连接中识别和存储用户数据。
sgcWebSockets 库允许您创建自定义对象并将其关联到 TsgcWSConnection 类,从而在收到新消息、客户端断开连接时随时访问自定义对象。现在,您可以将分组的易用性与自定义对象相结合,轻松构建高级应用程序。
用户认证
服务器将配置为仅接受已认证的用户连接,因此首先需要在服务器端启用认证,然后配置 OnAuthentication 事件以验证服务器收到的连接。用户通常存储在数据库中,本示例中为简单起见对用户进行硬编码。
Server.Authentication.Enabled := True; Server.Authentication.Basic.Enabled := True;
以下是示例代码:首先判断用户名/密码是否已知,若正确则创建 TsgcUser 类的新实例并填充用户数据,然后赋值给 Connection.Data 属性。这样,当您收到该用户的消息、或该用户断开连接时,均可访问其用户数据。
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;
用户认证成功后,将触发 OnConnect 事件,此时可以将用户添加到分组。在本示例中,用户的 Department 属性将用作分组名称。您可以多次调用 Groups.Add 方法将一个连接添加到多个分组。
procedure OnServerConnect(Connection: TsgcWSConnection); begin Server.Groups.Add(TsgcUser(Connection.Data).Department, Connection); end;
当客户端断开连接时,连接类会自动从 Groups 属性中移除,无需手动删除。
使用事件
Groups 属性提供 2 个事件,分别在用户加入或离开分组时通知。
OnClientAdded:当新连接加入分组时触发。
OnClientRemoved:当现有连接从分组移除时触发。
可以在服务器启动前配置这些事件。以下示例中,当有新成员加入或现有成员断开连接时,向该分组的所有成员发送一条消息。
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;
发送消息
您可以使用 Groups 向特定分组、多个分组广播消息,以下是一些示例。
// 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.');
以下提供服务器和客户端应用程序的源码及 Windows 编译好的二进制文件。
