web-dev-qa-db-ja.com

オフライン/オンラインデータ同期設計(Javascript)

私は現在、オフラインサポート用のすべてのhtml5グッズを使用してオフラインWebアプリを作成しているところです。ただし、オフラインデータがサーバーに送信され、サーバーデータがクライアントに返されるようにする同期モジュールの作成について考え始めています。これは以前に行われたことがあると確信しています。つまり、モバイルデバイスやその他の多くのことに影響を与える、かなり古典的な設計上の問題です。だから私は誰かが私にこの種のもののためのいくつかの良いデザインリソースを指摘できるのだろうか?

今、私はこれであまり洗練されている必要はありません。つまり、同じデータにアクセスする複数のユーザーを処理しておらず、競合をマージしないことを嬉しく思います(最新のものを取得するだけです)が、それでも将来、それらのオプションを許可してください。

また、この種のことを実装しているオープンソースプロジェクトはありますか?私は他の誰かのコードを(ライセンスが許せば)取り除いているだけではなく、移植できてうれしいです。

54
gatapia

同様の設計(まだ試していません)の私の計画は、 PouchDB のようなものを使用してデータをローカルに保存し、それをリモートのcouchインスタンスと同期することです。

10
kybernetikos

私も同様の問題を抱えていました。私は純粋にJSONの入出力アプローチを使用することにしました。私がフォーム送信で取っている解決策は次のとおりです。

  1. フォーム送信イベントをキャッチ
  2. ユーザーがオンラインかどうかを確認します
  3. ユーザーがオンラインの場合、通常のフォームPOSTとしてフォームを送信します
  4. userがオフラインの場合、JSONリクエストを文字列化し、ローカルに保存します(Web SQLデータベースを使用することにしました)。キューテーブルは単にURIとペイロードです。

次に、オンライン/オフラインイベント用のグローバルイベントフックがあります。ユーザーがオンラインに戻ると、キューをチェックし、キューにアイテムが含まれている場合は、JSON POSTリクエストとして送信します。

主にJSONデータの取得とオフラインでの使用のためのキャッシュに関心がある場合は、 jquery.offline をご覧ください。

両方向で同期する場合の課題は、キューに入れたCRUD作業でローカルキャッシュリストを更新する必要があることです。

これを行うためのより一般的な方法を見つけたいと思います。

9
Rebecca

Derbyをチェックしてください。Node非常に優れた同期機能と競合解決機能を備えたMVCフレームワークです。 http://derbyjs.com/

6
frontendbeauty

私たちのチームでは、すでにオフライン/オンラインモードでアプリを開発しています。

次のライブラリを使用しています。

ラックオフラインを使用して、ページにコンテンツをレンダリングするためのすべてのリソースファイルとjstテンプレートをキャッシュしています。バックボーンjsとバックボーンjs-localStorageは、クライアントでMVCアプリを作成するのに役立ちます。それはかなり素晴らしいです、あなたはそれを試してみるべきです。データの保存には常にlocalstorageを使用しています。たとえばモデルオブジェクトの投稿を作成してlocalStorageに保存すると、同期のためにキューがトリガーされます(同期プロセスを自動実行するためのタイマーバックグラウンドワーカーもあります)。モデルごとに、キュー同期トリガーによって実行される個別の同期クラスがあります。 navigator.onLine => trueの場合、更新用のデータを含むリクエストをサーバーに送信します。ブラウザを閉じても、localStorageにキューがあるため、とにかくデータが失われることはありません。次回、クライアントは最初のロード時にnavigator.onLine => trueでデータを同期します。

ラックオフラインの使用方法は、githubで私の小さなプロジェクトを確認できます。

pomodoro-app

幸運を!

4
oivoodoo

潜在的に重いExtJS/Senchaフレームワークを使用する場合は、オフライン(localStorageなど)をサポートするNiceデータAPIと、ローカルサーバーへのライトスルーのプロキシアプローチがあります。私はSenchaTouch(モバイル固有)を使用しています。

Webストレージのデバッグについては、Weinreをご覧ください。

1
Will

DerbyJSがおそらく最良の解決策でした。ただし、ダービーはまだ開発中であり、オフラインサポートは計画中であり、まだ実装されていません。 Googleグループ( http://groups.google.com/group/derbyjs/browse_thread/thread/7e7f4d6d005c219c )では、将来計画されている内容に関する追加情報を見つけることができます。

1
yannisgu

私は同じ問題に直面し、接続が利用可能になるとすぐに、ストレージとgitにXMLファイルを使用して変更を追跡し、それらを自動的にコミットすることになりました。同期は、シェルスクリプトの通常のgit commit/Push/pullコマンドと、スクリプトを開始するcronjobを使用して実行されます。これは、JSONをテキストファイルに保存する場合にも機能します。

1
brains_at_work

個人的には、indexedDB APIの上に、オンラインかオフラインかをチェックするラッパーを作成することをお勧めします。

  • オフラインの場合は、indexedDBに保存し、すべてのドキュメントで永続化フラグをfalseに設定するだけです
  • オンラインの場合、persistedがfalseのすべてのドキュメントを取得し、それらをmongodbまたはバックエンドの同等のものに保存してから、新しいドキュメントを、persistedフラグをtrueに設定してindexedDBとサーバーの両方に保存します。

私は小さなものを書きました

永続化フラグを自動的に設定し、これらのドキュメントの同期をバックエンドにトンネリングするには、トンネルを拡張する必要があります。

1
Raynos

私は現在、同様のWebアプリに取り組んでいます。私はそのようなワークフローを作ることにしました:

  1. フォームは実際には送信されません-[送信]ボタンは実際にシリアル化されたフォームデータをlocalStorage(一部のキュー)に保存します。これにより、送信のキャプチャに関する問題や、フォーム送信中の切断を処理するための追加のエラー処理コードの記述が不要になります。
  2. トランスポートスクリプトは、データの保存後にトリガーされます。オンライン/オフラインの状態をチェックします。
  3. オンラインの場合、キューからサーバーに最新のデータを送信しようとし(AJAX要求)、成功するとキューから削除します(そして、短いタイムアウトの後もキューから次のデータを送信し続けます)。
  4. しばらくすると(setTimeout()による)再チェックを実行します。
1
Victor