メインコンテンツまでスキップ

クライアント接続の管理

Squid Backend SDK には、バックエンドがサーバーへのクライアント接続をリアルタイムで検知できる機能があります。

この機能により、Squid バックエンドに対するクライアントの接続性を監視・管理でき、次のことが可能になります。

  • クライアントの接続・切断に関するリアルタイム情報を取得する
  • ユニークな client ID を活用してクライアント接続を把握する
  • 接続状態に応じて特定のアクションを実行する

クライアント接続の扱い方

Squid は、クライアントの接続状態の変化を処理するために使える decorator を提供します。これは、ベースの SquidService クラスを拡張したクラス内で、関数に @clientConnectionStateHandler decorator を付与することで実現します。この decorator 内に、望む挙動を実行するためのカスタムコードを追加できます。

@clientConnectionStateHandler decorator は 2 つのパラメータを受け取ります。

  • 接続を開始した ClientId(string として受け取ります)
  • クライアントの現在の接続状態を含む ClientConnectionState。値は次の 3 つのいずれかです:
    • CONNECTED はクライアントが接続中であることを示します
    • DISCONNECTED はクライアントがたった今切断したことを示します
    • REMOVED はクライアントが切断し、Squid がその ClientId を削除したことを示します。これは、次回そのクライアントが接続すると新しい ClientId になることを意味します

クライアント接続の理解

クライアント接続は Squid の強力な機能です。利用方法をさらに理解するために、ユーザーのオンライン状態を表示する チャットルームの例 を使ってみましょう。

各クライアントの Squid サーバーへの接続を活用するプロセスには、いくつかの重要なステップがあります。

  1. クライアントが最初に接続すると、Squid がユニークな clientId を割り当てます
  2. ユーザーが認証されたら、各ユーザーのオンライン状態を追跡するために、対応する clientId とその userId を紐付けられます
  3. クライアントがチャットルームに参加したら、ユーザーステータスの collection に挿入して、チャットルーム内に存在する clientIds とそれに紐づく userIds を保存できます
  4. @clientConnectionStateHandler decorator を使ってクライアントの切断を検知し、対応するユーザーの状態を offline に更新できます
  5. @clientConnectionStateHandler decorator を使ってクライアントが removed されたことを検知し、ユーザーステータスの collection から対応するユーザーを削除できます

接続時に各クライアントへユニークな clientId を付与することで、個々のユーザー状態を正確に追跡・管理できます。 この機能により、userIds をそれぞれの clientIds と関連付けられ、クライアントの存在(presence)をリアルタイムに監視できます。

クライアント側の接続状態

クライアントでこのフローを利用するために、Squid は次のオプションを提供します。

  • squid.connectionDetails().connected: クライアントが現在サーバーに接続されているかどうかの boolean を返します
  • squid.connectionDetails().observeConnected(): クライアントがサーバーに接続されると true、サーバーから切断されると false を emit する observable を返します
  • squid.connectionDetails().clientId: 現在のクライアントに割り当てられた clientId を返します

バックエンド側の接続状態

バックエンドでこのフローを利用するために、Squid は次のオプションを提供します。

  • 上記で説明した @clientConnectionStateHandler decorator
  • this.context.clientId: このリクエストを開始したクライアントの id を返します

チャットルームの例

以下は、チャットアプリケーションでこのプロセスを管理する基本的な例です。@clientConnectionStateHandler decorator を使用することで、クライアントはチャットルームに存在するすべてのユーザーと、それぞれの状態(オンラインかオフラインか)を一覧として取得できます。

接続されている clientIds は分かりますが(どの userIds かは分からないため)、各ユーザーのオンライン状態を追跡するには、各接続の clientId を対応する userId に紐付ける必要があります。

そのために、ユーザーがチャットルームに参加するたびに status collection を mutate できます。この collection では、document ID として clientIds を持ち、挿入するデータは userId とその状態です(ユーザー参加時に関数を実行するため、状態は online になります)。

ユーザーが新しい接続を確立するたびに collection を更新できます。observeConnected() 関数(クライアントがサーバーに接続すると true を返す)が、接続確立後に mutation をトリガーします。

Client code
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
)

この mutation を実行することで、ユーザーのオンライン状態を初期化するために clientIdsuserIds を紐付けます。

Note

Squid と認証について詳しくは、認証プロバイダーと Squid を統合するためのドキュメントをお読みください。

次のステップは、ユーザーのオフライン状態を監視することです。ここで @clientConnectionStateHandler decorator が不可欠になります。 clientIdDISCONNECTED になることは、ユーザーがチャットルームからログオフしたことを表します。したがって、ユーザーの状態を offline に更新する必要があります。 さらに、clientIdREMOVED になることは、ユーザーがチャットルームを離れたことを表します。

Backend code
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();
}
}
}

その後クライアントは、チャットルーム内のユーザー一覧とそれぞれの状態を取得するために、userPresence collection をqueryできます。

Squid におけるクライアント接続の監視方法と、それに対するリアクションの方法を理解することで、 ユースケースに応じてこれらの接続性の変化をより効果的に管理できます。