Що робити, коли запит надсилається на сервер і під час очікування втрати підключення до Інтернету?


14

Я надсилаю величезну кількість даних на сервер. Тепер, коли я надсилав дані і чекаю відповіді сервера, раптом мій андроїд-пристрій втрачається підключення до Інтернету.
Тож те, що я раніше робив, - це показ діалогового вікна попередження про втрату з'єднання, але на стороні сервера дані вже оброблені та десь оновлені, наприклад, на будь-якій URL-адресі. Але мій андроїд телефон цього не знає, оскільки не отримав відповіді ніколи. Як це вирішити.
Чи можна це зробити на стороні сервера чи на самому Android як?
Як сервер знав би, що телефон Android не збирається слухати відповідь?
Це може бути перспектива оптимізації спілкування клієнт-сервер.


Про скільки ми говоримо? Гігабайти?
Даніель Холлінрак

Не багато 7-8 Мб, але час відгуку сервера занадто довгий, а швидкість завантаження з телефону становить близько 128 КБ / с. Я не говорю про розмір даних, а про проблему з підключенням.
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-пошти для надсилання запиту на сервер, використовуючи унікальний ідентифікатор запиту клієнта - і сервер відповість ідентифікатором завдання. З точки зору клієнтів, якщо такої відповіді не виникає, запит потрібно повторно надіслати. З точки зору сервера клієнтський ідентифікатор запиту потрібно кешувати протягом декількох хвилин, на випадок, коли клієнт надсилає повторювані запити. Дублювання запитів обробляється просто шляхом повернення клієнту того ж ідентифікатора завдання.

Клієнт отримує результати запиту з URL-адреси результатів. Цей дзвінок можна повторювати стільки разів, скільки потрібно для отримання результатів. Якщо його виклик до появи результатів, то відповідь може бути відповіддю NO-CONTENT, тому клієнт знає, що сервер розпізнає ідентифікатор завдання, але ще не має вмісту. Якщо ідентифікатор завдання не розпізнається, відповідна відповідь NOT-FOUND.

Кінцевим результатом є те, що клієнт завжди може зробити розумні дії, коли мережа втрачена та відновлена, і також сервер завжди може обробляти запити клієнта.


3
Це або просто зробити короткий запит із запитом ідентифікатора транзакції, потім декілька запитів, що додають дані до транзакції (ви можете розділити передачу на менші шматки тут, щоб отримати часткове підтвердження), а потім остаточний запит на "здійснення". Потім у вас можуть бути різні тайм-аути для повністю порожніх транзакцій (найімовірніше, клієнт не отримав ідентифікатор), частково завантажених транзакцій та результатів (якщо клієнт не отримав результатів, він може повторно просити запит "зробити").
Саймон Ріхтер

Це дозволило б керувати ситуацією, коли зв’язок втрачався під час передачі запиту. Задане запитання - це питання про з’єднання, втрачене після надсилання даних, але перед тим, як запит завершився.
Майкл Шоу

1
Це також обробляється. Угода "фіксувати" невелика і використовує ідентифікатор транзакції, тому її можна переоформити дешево без повторної передачі даних, і сервер може або почати обробку, або повернути результат з попереднього виклику. Це дуже схоже на те, що ви пропонуєте; Різниця полягає в тому, що у мене є окремий запит на створення ідентифікатора завдання, тому у мене є додаткова точка синхронізації, тому клієнт може знати, чи існує вже робота без повторної передачі повного запиту.
Саймон Ріхтер

так, це має сенс.
Майкл Шоу

Таким чином, якщо транзакція містить часткові дані на сервері, я знаю, що існує клієнт, який знає цей ідентифікатор і намагається завершити транзакцію, тому я можу зберегти частковий стан і запропонувати відновити передачу на півдорозі, мінімізуючи вимоги пропускної здатності та видаляючи потрібно порівняти вміст запиту, щоб знайти дублікати.
Саймон Ріхтер

4

Це підпадає під основи протокольного спілкування. Клієнт Android запитував транзакцію, і Сервер повинен здійснити транзакцію. Якщо транзакція залежить від підтвердження клієнта Android, це дзвінок ACK / NAK.

ACK (підтвердження) та NAK (негативне підтвердження) використовуються для того, щоб повідомити стороні результат запиту.

Те, про що ви запитуєте, - це тип обміну рукостисканням між клієнтом і сервером, і він може здійснюватися за допомогою базового обміну ACK / NAK.

Ось приклад завантаження файлу Android з двостороннім підтвердженням для 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 **/

У наведеному вище прикладі Сервер прийняв завантажені файли і відправив відповідь #idACK назад на Android, але Android ніколи не відповідає ACK. Пристрій Android не вдалося завершити обмін руками. Ви вирішуєте, як Сервер повинен це впоратися. Знищіть транзакцію, утримуйте транзакцію і дочекайтеся, коли пристрій Android повернеться пізніше або все одно завершить транзакцію.

Сервер може припустити, що оскільки пристрій не відповів ACK. Те, що пристрій Android не оновлювало його внутрішній стан, свідчить про те, що завантаження було успішним. Я б відкинув транзакцію і дозволю пристрою повторити її в майбутньому.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.