要求がサーバーに送信され、応答を待っている間にインターネット接続が失われた場合の対処方法


14

サーバーに大量のデータを送信しています。データを送信してサーバーからの応答を待っている間に、Androidデバイスが突然インターネット接続を失います。
だから、私がやったことは、接続が失われたという警告ダイアログを表示することですが、サーバー側ではデータが既に処理されており、URLなどでどこかで更新されました しかし、私のアンドロイド携帯電話は、これまでに応答を得られなかったので、これを知りません。解決方法。
サーバー側で実行できるのか、それともアンドロイド自体で実行できるのか
Androidフォンが応答をリッスンしないことをサーバーはどのように知るのでしょうか?
これは、クライアントとサーバー間の通信の最適化の観点かもしれません。


どれくらいのデータについて話しているのですか?ギガバイト?
ダニエルホリンレイク

およそ7〜8 MBですが、サーバーの応答時間は長すぎ、電話からのアップロード速度は約128 KB / Sです。データサイズではなく、接続の問題について話している。
mayank_droid

回答:


15

これは非同期トランザクションではかなり一般的な問題であり、いくつかの部分に分類されます。

  1. トランザクション要求が正常に受信されたことを両側でどのように知るのですか?
  2. クライアントが適切に受信されていないと考えているトランザクション要求をどのように再送信しますか?
  3. サーバーが最初の要求を正常に受信したときに、サーバーはクライアントからの繰り返し要求をどのように検出しますか?
  4. クライアントは、トランザクションの結果をどこから取得するかをどのように知るのですか?

HTTPの素晴らしい点は、これらの問題をすべて簡単に解決できることです。

次のようなURL構造を想像してください。

POST http://my.server.com/application/engine/queue 
GET   http://my.server.com/application/engine/results?jobid=43425

HTTPポストを使用して、一意のクライアント要求IDを使用してサーバーに要求を送信し、サーバーにジョブIDで応答させます。クライアントの観点から、この応答が発生しない場合は、リクエストを再送信する必要があります。サーバーの観点からは、クライアントが重複したリクエストを送信する場合、クライアントリクエストIDを数分間キャッシュする必要があります。重複した要求は、同じジョブIDをクライアントに返すだけで処理されます。

クライアントは、結果URLからリクエストの結果を取得します。この呼び出しは、結果を取得するために必要な回数繰り返すことができます。結果が利用可能になる前に呼び出された場合、応答はNO-CONTENT応答である可能性があるため、クライアントはサーバーがジョブIDを認識しているがコンテンツがまだないことを認識します。ジョブIDが認識されない場合、NOT-FOUNDが適切な応答です。

最終結果は、ネットワークが失われ、回復されたときにクライアントが常に賢明なアクションを実行できることです。同様に、サーバーはクライアントからの要求を常に賢明に処理できます。


3
それ、または単にトランザクションIDを要求する短いリクエストを実行し、次にトランザクションにデータを追加するいくつかのリクエスト(ここで転送を小さなチャンクに分割して部分的な確認を取得できます)、最後の「コミット」リクエスト。その後、完全に空のトランザクション(クライアントはおそらくIDを受信しなかった可能性が高い)、部分的にアップロードされたトランザクション、および結果(クライアントが結果を受信しなかった場合、「コミット」リクエストを再試行できます)に対して異なるタイムアウトを設定できます。
サイモンリヒター

これにより、リクエストの送信中に接続が失われた状況を管理できます。質問は、データが送信された後、リクエストの処理が完了する前に失われた接続についての質問です。
マイケルショー

1
それも処理されます。「コミット」トランザクションは小さく、トランザクションIDを使用するため、データを再送信せずに安価に再発行でき、サーバーは処理を開始するか、以前の呼び出しから結果を返すことができます。これは、あなたが提案していることに非常に似ています。違いは、ジョブIDを作成する別の要求があるため、追加の同期ポイントがあるため、クライアントは完全な要求を再送信せずにジョブが既に存在するかどうかを知ることができることです。
サイモンリヒター

ええ、それは理にかなっています。
マイケルショー

このように、トランザクションにサーバー上の部分的なデータが含まれている場合、このIDを認識してトランザクションを完了しようとするクライアントが存在することがわかっているため、部分的な状態を維持し、送信を途中で再開することを提案して、帯域幅要件を最小限に抑え、重複を見つけるためにリクエストの内容を比較する必要があります。
サイモンリヒター

4

これは、プロトコル通信の基本に該当します。Androidクライアントからトランザクションが要求され、サーバーはトランザクションを実行する必要があります。トランザクションがAndroidクライアントの確認応答に依存している場合、これはACK / NAK通信の呼び出しです。

ACK(肯定応答)とNAK(否定応答)は、要求の結果を相手側に伝えるために使用されます。

求めているのは、クライアントとサーバー間のハンドシェイク交換の一種であり、基本的なACK / NAK交換で実行できます。

以下は、Androidが双方向確認でファイルをアップロードする例です。

Android -> upload files -> Server
Android <- ACK #id <- Server
Android -> ACK #id -> Server

上記の例では#id、トランザクションに一意の識別子を追加しました。サーバーはファイルを受信し、トランザクションレコードを作成し、応答としてAndroidに送信します。その後、Androidはそのトランザクションの承認(または拒否の場合はNAK)を確認する必要があります。

以下は、ハンドシェイク中にAndroidが切断する例です。

Android -> upload files -> Server
Android <- ACK #id <- Server
/** no ACK response **/

上記の例では、サーバーはアップロードされたファイルを受け入れ、#idAndroidにACK応答を送信しましたが、AndroidはACKで応答しません。Androidデバイスはハンドシェイクを完了できませんでした。サーバーがこれを処理する方法を決定するのはあなた次第です。トランザクションを破棄し、トランザクションを保持し、Androidデバイスが後で戻るか、トランザクションを完了するまで待ちます。

サーバーは、デバイスがACKで応答しなかったためと想定できます。Androidデバイスが内部状態を更新せず、アップロードが成功したことを示します。トランザクションを破棄し、デバイスが将来それを繰り返すことを許可します。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.