Atlas Device Sync プロトコル
項目一覧
Overview
Atlas Device Sync は、 プロトコルを使用して、それぞれがローカルの Realm ファイルを保持する複数のクライアント間でデータの変更をリアルタイムで正しく効率的に同期します。 このプロトコルは、事前定義されたリクエスト タイプのセットと、Realm SDK などのクライアントが Atlas App Services アプリケーション サーバーに接続してデータを同期するためのプロセスを定義します。
注意
Realm SDK は同期プロトコルを内部的に実装および管理するため、ほとんどのアプリケーションにおいて Device Sync を使用するために同期プロトコルを理解する必要はありません。 このページでは高レベルのプロトコルを説明しており、実装仕様ではありません。
重要な概念
変更セット
変更セットは、1 つ以上の書込み操作によって既知のオブジェクトの状態またはバージョンに対して行われた詳細な変更を説明する指示のリストです。 変更セットは、同期プロトコルの基本単位です。 同期された Realm クライアントは、書込み操作を実行するたびに変更セットを Device Sync サーバーに送信します。 サーバーは、接続された各クライアントに、他のクライアントによって実行された書込み (write) 操作の変更セットを送信します。
Device Sync サーバーは、接続された同期クライアントからの変更セット(同期された MongoDB クラスターの変更を含む)をいつでも受け入れ、運用変換アルゴリズムを使用して変更を線形順序で直列化し、競合する変更セットを接続クライアントに送信する前に解決します。
注意
差分同期
同期されたオブジェクトに変更を加えても、App Services はオブジェクト全体を再アップロードしません。 代わりに、App Services は変更前と変更後の差(「デルタ」)のみを送信します。 サービスは zlib でデルタを圧縮します 圧縮。これによりネットワーク負荷が軽減され、モバイル ネットワークの条件において特に有用です。
運用上の変換
演算子変換とは、2 つの変更セットの場合、指定された変更セットの一方を論理的に適用することを表す 3 つ目の変更セットを生成する関数です。 Device Sync は 運用変換 を使用して、同じ基本状態に適用される異なる同期クライアントからの変更セット間の競合を解決します。
Realm は、同期が有効になっている場合でも、オフライン ファーストのローカル データベースです。つまり、ネットワーク接続が再確立されたときに、どのデバイスもオフライン書き込みを実行し、対応する変更セットをアップロードできます。 運用変換アルゴリズムは、同期されたすべての Realm ファイルが変更された各オブジェクトの同じバージョンに統合されるように、論理サーバーのクロックに対して「順序」から順に到着した変更セットを正常に処理するように設計されています。
Tip
Realm 変更セットでの運用変換は 再ベース操作 に類似 Git 。
クライアント ファイル識別子
クライアント ファイル識別子は、同期されたクライアントの Realm ファイルとそれに対応するサーバー ファイルを一意に識別する値です。 サーバーは、Realm ファイルの最初の同期中に SDK が要求するたびにクライアント ファイル識別子を生成します。 各識別子は 64 ビットのゼロ以外の正の符号付き整数で、2 ^ 63 未満です。
注意
サーバーは、特定のサーバー ファイルに代わって生成されたすべての識別子が互いに一意であることを保証します。 サーバーは、異なるサーバー ファイルに関連付けられている場合、2 つのクライアント ファイルに対して同一の識別子を無料で生成できます。
ネットワークセキュリティ
SDK は、 TLS を使用して、HTTPS1.3 によって保護された WebSocket 接続を介してアプリケーション サーバーと同期します。
同期セッション プロセス
Device Sync セッションを開始、実行、終了するために、Realm SDK とアプリケーション サーバーはプロトコル固有のリクエストのセットを送受信します。
SDK は HTTP 経由で WebSocketBIND
IDENT
接続をネゴシエートし、WebSocket 接続経由でサーバーに リクエストと リクエストを送信して同期セッションを確立します。セッションが確立されると、SDK とサーバーは特定の Realm ファイルの同期された変更セットをUPLOAD
} メッセージとDOWNLOAD
メッセージを介して相互に送信します。 セッションを終了するには、SDK はUNBIND
リクエストを送信します。
Realm SDK App Server | | | <---- 1. HTTP Handshake -----> | | | | --------- 2. BIND -----------> | | | | <-- 3. IDENT (first time) ---- | | | | --------- 4. IDENT ----------> | | | | <---- 5. UPLOAD/DOWNLOAD ----> | | | | --------- 6. UNBIND ---------> |
アプリ サーバーへのクライアント接続
同期プロトコルは、主に SDK とサーバー間の WebSocket 接続を介して処理されます。 接続を確立するために、SDK は次の内容を含むハンドシェイク HTTP リクエストを送信します。
プロトコルバージョン
WebSocket キー
認証された App Services アプリケーション ユーザーの有効な アクセス トークン
サーバーが HTTP101 スイッチ プロトコル を送信する SDK の WebSocket 接続を指定する応答。同期プロトコルの残りの部分は、この接続を介して行われます。
クライアントによる同期セッションの開始
同期セッションを開始するために、Realm SDK は Device Sync サーバーにBIND
リクエストを送信します。 このリクエストは、同期する特定のローカル Realm データベース ファイルを識別し、サーバーが SDK への双方向接続を開くために使用する WebSocket 接続キーを含みます。
SDK が特定の Realm Database ファイルを初めて同期しようとする場合、ファイルのサーバーが生成したクライアント識別子はまだ存在しません。 この場合、 BIND
リクエストは、Device Sync サーバーが 1 を割り当てる必要があることも示します。
App Services による新しいクライアント ファイル識別子の割り当て
BIND
リクエストが SDK にクライアント ファイル識別子が必要であることを示す場合、Device Sync サーバーは指定された Realm データベース ファイルに対して一意の 値を生成し、それをIDENT
応答で SDK に送信します。 SDK がIDENT
を受信すると、新しいクライアント識別子をローカルの Realm Database ファイルに永続的に保存します。
SDK は、各 Realm データベース ファイルを初めて同期するときにのみクライアント ファイル識別子を要求する必要があります。 後続の同期セッションでは、SDK は永続化された識別子を使用できます。
クライアントがクライアント識別子を送信
SDK がBIND
リクエストで同期セッションを開始したら、同期するローカル Realm Database ファイルを識別する必要があります。 そのために、SDK はクライアント ファイル識別子を含むIDENT
メッセージをアプリケーション サーバーに送信します。 SDK が以前に Realm をサーバーと同期したことがある場合は、同期プロセスを最適化するために最後に同期されたサーバー バージョンを指定できます。
サーバーはIDENT
メッセージを受信すると、セッションを確立します。 SDK とサーバーは、いつでも同期の変更セットをいつでも自由に送信できるようになりました。
クライアントによる同期変更セット
同期セッションが確立されると、SDK とサーバーはUPLOAD
とDOWNLOAD
メッセージを自由に送受信でき、変更が発生するたびに同期できます。
SDK は、サーバーから メッセージで受信した変更を除く、適用されるすべての変更セットに対してUPLOAD
DOWNLOAD
メッセージを送信します。
サーバーはUPLOAD
メッセージを受信すると、運用変換を適用して他の変更セットとの競合を解決し、変換された変更セットを Realm のサーバー バージョンに適用します。 これによりサーバーはトリガーされ、サーバー邦土をミラーリングする同期された Atlas クラスターなど、接続されている他のクライアントにDOWNLOAD
メッセージを送信します。 DOWNLOAD
メッセージは、1 つ以上の変換された変更セットを、サーバーの履歴に従って、最も古いものから最新のものまで時系列でグループ化します。 SDK は変更セットを同じ順序で適用します。
リクエスト タイプ
クライアント -> サーバー メッセージ
次の表では、同期クライアントが Device Sync サーバーに送信できるリクエストの種類について説明します。
リクエスト | 説明 |
---|---|
サーバー上で新しい同期セッションを開始し、現在のアプリケーション ユーザーに署名された認可トークンを提供します。 クライアントが同期する Realm ファイルのクライアント ファイル識別子をまだ持っていない場合は、サーバーが識別子を生成し、クライアントに送り返す必要があることも示します。 クライアントは、他のリクエストを送信する前に、BIND を送信する必要があります。 | |
次の内容を示すクライアント ファイル識別子を提供します。
このリクエストは、クライアントが クライアント ファイル識別子をリクエストしたときにサーバーが送信する | |
クライアントで発生した操作の 1 つ以上の変更セットを指定します。 変更セットは、クライアントのバージョン別に昇順で表示されます。 | |
クライアント上で発生したシリアル化されたトランザクションを記述する変更セットを指定します。 サーバーがトランザクションを確認または拒否するまで、クライアントは他の変更セットをアップロードできません。 | |
実行中の同期セッションを終了します。 クライアントは | |
サーバーがクライアントにサーバー履歴(リクエストの時点で)最新の変更セットを同期したときを通知することを要求します。 | |
現在の同期セッションを新しいユーザー トークンで再認可します。 | |
サーバーが 1 つ以上の STATE メッセージを送信することをリクエストします。このメッセージは、クライアントが Realm ファイルの現在のサーバー バージョンをダウンロードするために使用します。 クライアントは、同期された Realm を非同期に開くときに状態リクエストを発行します。 | |
クライアントによって送信され、サーバーによって処理された最新の変更セットのクライアント バージョンをサーバーが送信することを要求します。 これは、SDK がクライアント リセットを実行するときに最も一般的に使用されます。 | |
クライアントがまだ接続されており、サーバーが同期セッションを維持する必要があることを示します。 クライアントは10分ごとに少なくとも 1 つの PING をサーバーに送信する必要があります。 サーバーは サーバーが 10 分以上クライアントからの PING を受信しない場合、クライアントは切断されたと見なされ、セッションが自動的に終了することがあります。 |
サーバー -> クライアント メッセージ
次の表では、Device Sync サーバーが同期クライアントに送信できるリクエストの種類について説明します。
リクエスト | 説明 |
---|---|
識別子をリクエストした に応答してサーバーが生成した クライアント ファイル識別子 BIND を提供します。 | |
サーバーがクライアントからの TRANSACT で指定された変更セットを正常に処理したかどうかを示します。 | |
サーバーがクライアントから を受信したときにサーバー履歴にあった最新の MARK 変更セット をサーバーがクライアントに送信したことを示します。 | |
クライアントが連結して Realm の最新のサーバー バージョンを構築できるエンコードされたデータの 1 つ以上のセグメントが含まれます。 STATE_REQUEST に応答して送信されます。 | |
クライアントによって送信され、サーバーによって処理された最新の変更セットのクライアント バージョンを指定します。 CLIENT_VERSION_REQUEST に応答して送信されます。 | |
接続済みクライアントが原因と思われる問題がサーバーで発生したことを示します。 詳細については、 「同期クライアント エラー」 を参照してください。 | |
PING を確認します。 クライアントが PING 確認応答を受信しない場合は、クライアントが現在ネットワーク経由でサーバーと通信できず、サーバーが対応するPING を受信していない可能性があることを示します。 |