グループと接続のマッピング

· 機能

以前の記事で 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; 

メッセージの送信

グループを使用して特定のグループや複数のグループにメッセージをブロードキャストできます。以下にいくつかの例を示します。

// 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 向けコンパイル済みバイナリを示します。