0

1 人のユーザーが複数のデバイスを使用してオフラインまたはオンラインでデータを生成する場合、データをマージして競合をできるだけ回避するにはどうすればよいですか?

オフライン容量のあるいくつかのステージでゲームを作ったように。ユーザーのマイクは、iPad のオフライン ステータスでスコア 123 でステージ 2 に到達しましたが、iPhone に移動すると、まだステージ 1 にいることがわかりました。そのため、ステージ 1 をもう一度プレイし、スコア 321 でステージ 2 に到達しました。彼の両方のデバイスがインターネットに接続されているため、これら 2 つのデバイスを 1 つのステータスに同期させたいと考えています。私たちはするかもしれません:

  • ユーザーが 2 つのデバイスで同期ボタンをクリックすると、アプリケーションが停止する
  • すべてのデバイスがすべてのユーザー データ (スコア、ステージなど) をプッシュします。
  • サーバーはユーザーデータを最終変更時刻とマージします
  • すべてのデバイスがマージされたデータを取得します
  • アプリケーションは最初のページに戻り、矛盾を避けるために再開します

このソリューションは、アプリケーション自体に依存しています。ユーザー データの同期をアプリケーションに対して透過的にするソリューションはありますか?

4

3 に答える 3

2

複数のユーザーが同じドキュメントを編集するとき、一種の共同作業のように聞こえます。

まず、共同作業をどのように実装するかを見てみましょう。

  • クライアント イベントはサーバーに送信する必要があります。
  • サーバーがイベントの順序を設定し、
  • サーバーはデータにイベントを適用し、
  • サーバーはデータの変更をクライアントに送信します。

サーバーが常にアクセス可能であれば、うまく機能します。私は共同スプレッドシートを書きましたが、セルに 1.9999999 を入力すると 2.00 に変わったのは素晴らしいことでした。1.9999999 は単なるイベントであり、サーバーがそれを処理して 2.00 データを作成し、送り返したからです。

サーバー 7/24 が利用できない場合は、

  • データのローカル コピーを保持し、
  • ドラフトイベントを使用-> データ変換、
  • サーバーが公式データを送信するまで、どのドラフトデータが表示されますか。

ほとんどの場合、公式データとドラフト データは同じであり、ユーザーが見ることができるのは一時的なデータであることをユーザーに警告する必要さえありません。

主なトリックは、

  • イベントにはタイムスタンプが必要です。
  • クライアントの時刻を同期する必要があります。

そのため、サーバーが休暇から戻ったときに、イベントを正しい順序で再生できるようになります。また、オフライン期間後に別のクライアントが参加し、過去のイベントを送信した場合、サーバーは他のクライアントからの過去のイベントを再実行して、正しい最終データを計算する必要があります。

すべてのイベントがサーバーによって収集されるかどうかはわかりません。はるか昔の出来事をどうするか、戦略を立てなければなりません。多分それらを落としますか?

場合によっては、ハイスコアなど、順序は重要ではありません。

于 2013-11-08T14:58:03.427 に答える
0

最善の解決策は、両方のデバイスが同時にインターネットに接続され、両方のボタンが押されることを要求しないことだと思います。

あなたはこのようにすることができます:

  1. 起動時に、アプリケーションはインターネット接続があるかどうかを確認します。そうでない場合は、独自のデータに基づいて開始します。それ以外の場合は、ユーザー データをサーバーにプッシュします。
  2. サーバーがデバイスからユーザーデータを取得すると、マージが行われます: あなたのケースでは、ステージが既に知っているものよりも高いかどうかを確認する必要があります: そうでない場合は、新しく受信したデータを無視し、そうでない場合は既存のデータを上書きします新しく受信したデータ。
  3. データが更新された場合、サーバーは接続されているすべてのデバイスに新しいデータをブロードキャストします (これはゲーム中に発生する可能性があります)。

サーバーが接続されたデバイスを認識していない場合、手順 3 は機能しません。解決策は、ステップ 1 を変更して、起動時にアプリケーションがユーザー データをサーバーにプッシュし (すぐにマージを実行します)、サーバーからユーザー データをクエリし (同じかそれ以上のステージになる可能性があります)、開始するようにします。受け取ったものに基づいています。

于 2013-11-08T15:58:00.010 に答える
0

サーバーでトランザクション データベースを使用します。

ウィキペディアから:

  1. 取引を開始する
  2. 一連のデータ操作および/またはクエリを実行する
  3. エラーが発生しない場合は、トランザクションをコミットして終了します
  4. エラーが発生した場合は、トランザクションをロールバックして終了します

サーバーベースのデータベースは、クライアントにとって有効な情報の主要な情報源です。クライアントが最新のスコアを知りたい場合、データベースにクエリを実行します。クライアントでは、 と を追跡local_scoreremote_scoreます。ユーザーに表示するのは ですlocal_score+remote_scoreが、スコアの更新をサーバーに送信するときは、ゲームのそのインスタンスlocal_scoreで獲得した部分のみを送信します ( )。デルタのみを送信するという考え方です。データベースは、受け取った新しいスコアを内部合計に単純に追加し、上記のトランザクション方式でそれを行います。

トランザクションの発生中にデータベースの関連部分をロックするため、データベースはほぼ同時に要求をキューに入れ、それらを順次実行することに注意してください。このロジックをすべて自分で構築することもできますが、非常に多くの優れ無料の データベースがあるため、そのうちの 1 つを使用するだけです。

この戦略により、クライアントは、サーバーが更新されるたびにサーバーと同じように最新の状態に保ちながら、ゲームの状態に関する信頼できる情報源になる責任をサーバーに押し付けることができます。もちろん、これはスコアだけでなく、複数のクライアント間で追跡する必要があるものすべてで行います。

于 2013-11-10T12:51:52.363 に答える