クライアント接続の管理
Squid Backend SDKは、バックエンドがサーバーへのクライアント接続をリアルタイムで検出する機能を提供します。
この機能により、Squidバックエンドへのクライアント接続を監視および管理でき、次の操作が可能になります:
- クライアントの接続および切断に関するリアルタイム情報の取得
- ユニークなクライアントIDを活用してクライアント接続を理解する
- 接続状態に基づいて特定のアクションを実行する
クライアント接続の処理
Squidは、クライアントの接続状態の変化を処理するためのデコレーターを提供します。これは、ベースの SquidService クラスを拡張するクラス内で、関数に @clientConnectionStateHandler デコレーターを適用することで実現されます。このデコレーター内に、望む動作を実行するためのカスタムコードを追加できます。
@clientConnectionStateHandler デコレーターは2つのパラメーターを取ります:
- 接続を開始した ClientId(文字列として受け取ります)。
- クライアントの現在の接続状態を含む ClientConnectionState。これは以下の3つの値のいずれかになります:- CONNECTEDはクライアントが接続されていることを示します
- DISCONNECTEDはクライアントが直前に切断されたことを示します
- REMOVEDはクライアントが切断され、Squidがその- ClientIdを削除したことを示します。つまり、次回クライアントが接続する際には、新しい- ClientIdが割り当てられます
 
クライアント接続の理解
クライアント接続はSquidの強力な機能です。よりその利用方法を理解するために、chatroom example を使って、ユーザーのオンライン状態が表示される例を見てみましょう。
Squidサーバーへの各クライアント接続を利用するプロセスには、いくつかの重要なステップがあります:
- クライアントが最初に接続すると、Squidはユニークな clientIdを割り当てます
- ユーザーが認証されると、対応する clientIdとuserIdをリンクさせ、各ユーザーのオンライン状態を追跡します
- クライアントがチャットルームに参加すると、ユーザーステータスのコレクションに挿入し、どの clientIdsとそれに紐づくuserIdsがチャットルームに存在するかを保存します
- @clientConnectionStateHandlerデコレーターを使用してクライアントの切断を検出し、対応するユーザーの状態をオフラインに更新します
- @clientConnectionStateHandlerデコレーターを使用してクライアントの削除を検出し、ユーザーステータスのコレクションから対応するユーザーを削除します
接続時に各クライアントにユニークな clientId が与えられることで、個々のユーザーの状態を正確に追跡および管理することが可能になります。この機能により、各 userId とそれぞれの clientId を関連付け、クライアントの存在をリアルタイムで監視できます。
クライアント側の接続状態
このフローをクライアント側で利用するために、Squidは以下のオプションを提供します:
- squid.connectionDetails().connected: クライアントが現在サーバーに接続されているかどうかのブール値を返します
- squid.connectionDetails().observeConnected(): クライアントがサーバーに接続されているときに true、切断されているときに false をエミットする observable を返します
- squid.connectionDetails().clientId: 現在のクライアントに割り当てられた- clientIdを返します
バックエンド側の接続状態
このフローをバックエンド側で利用するために、Squidは以下のオプションを提供します:
- 上記の Handling client connections で説明した @clientConnectionStateHandlerデコレーター
- this.context.clientId: このリクエストを開始したクライアントのIDを返します
Chatroom example
以下は、チャットアプリケーションにおいてこのプロセスを管理する基本的な例です。@clientConnectionStateHandler デコレーターを使用することで、クライアントはチャットルームに存在する全ユーザーとその状態(オンラインかオフラインか)を取得できます。
接続されている clientIds は分かるものの、どの userIds が対応しているかは分からないため、各接続の clientId と対応する userId をリンクさせ、各ユーザーのオンライン状態を追跡する必要があります。
そのため、ユーザーがチャットルームに参加するときにステータスコレクションを変更します。このコレクションには、clientIds がドキュメントIDとして含まれ、挿入されるデータは userId とその状態(ユーザーが参加するたびに実行されるため、online となります)が含まれます。
また、ユーザーが新たに接続を確立する際にもコレクションを更新できます。observeConnected() 関数(クライアントがサーバーに接続されると true を返す)が、接続確立時にミューテーションをトリガーします:
type StatusData = {
  userId: string;
  status: 'online' | 'offline';
};
...
squid.connectionDetails().observeConnected().pipe(
  filter(Boolean)
).subscribe(() =>
    squid
      .collection<StatusData>('userStatus')
      .doc(squid.connectionDetails().clientId)
      .insert({ userId, status: 'online' }).then(); // get userId from auth provider
)
このミューテーションの実行により、clientIds と userIds がリンクされ、ユーザーのオンライン状態が初期化されます。
より詳しくSquidと認証について知りたい場合は、こちらのドキュメントをご覧ください。
次のステップは、ユーザーのオフライン状態を監視することです。ここで @clientConnectionStateHandler デコレーターが不可欠となります。clientId が DISCONNECTED になることは、ユーザーがチャットルームからログオフしたことを意味します。したがって、ユーザーの状態をオフラインに更新する必要があります。さらに、clientId が REMOVED になることは、ユーザーがチャットルームから退出したことを示します:
import { SquidService, clientConnectionStateHandler } from '@squidcloud/backend';
import { ClientConnectionState, ClientId } from '@squidcloud/client';
export class ExampleService extends SquidService {
  ...
  @clientConnectionStateHandler()
  async handleClientConnectionStateChange(
    clientId: ClientId,
    connectionState: ClientConnectionState
  ): Promise<void> {
    if (connectionState === 'DISCONNECTED') { // user logged off
      await this.squid
        .collection('userPresence')
        .doc(clientId)
        .update({ status: 'offline' });
    } else if (connectionState === 'REMOVED') { // user left the chat
      await this.squid
        .collection('userPresence')
        .doc(clientId)
        .delete();
    }
  }
}
その後、クライアントは query を使用して、チャットルームに存在するユーザーとその状態のリストを取得できます。
Squidでクライアント接続を監視し、反応する方法を理解することで、接続状態の変化に対してより効果的に対応できるようになります。