как мобильное приложение взаимодействует с сервером

Best Practices для взаимодействия сервера и приложения

This post is also available in: Английский

как мобильное приложение взаимодействует с сервером. iOS Best Practices. как мобильное приложение взаимодействует с сервером фото. как мобильное приложение взаимодействует с сервером-iOS Best Practices. картинка как мобильное приложение взаимодействует с сервером. картинка iOS Best Practices.

Сейчас, в эпоху роста и развития мобильных приложений, всё более актуальным становится правильное построение клиент-серверного взаимодействия. При взаимодействии мобильного приложения с сервером следует обратить внимание на следующие моменты: гибкость, расширяемость, документирование, поддержка старых версий API, кеширование. В этой статье мы рассмотрим наиболее важные аспекты разработки и проектирование сервисов, которые помогут достичь лучших результатов.

Гибкость и расширяемость

как мобильное приложение взаимодействует с сервером. plJCK. как мобильное приложение взаимодействует с сервером фото. как мобильное приложение взаимодействует с сервером-plJCK. картинка как мобильное приложение взаимодействует с сервером. картинка plJCK.

Для обеспечения гибкости и расширяемости клиент-серверного взаимодействия мы используем при разработке RESTful API. Хороший RESTful API — тот, который можно менять легко и просто. Сервер может считаться RESTful, если он соответствует принципам REST. Когда вы разрабатываете API, который будет в основном использоваться мобильными устройствами, понимание и следование трем наиважнейшим принципам может быть весьма полезным. Причем не только при разработке API, но и при его поддержке и развитии в дальнейшем.

Независимость от состояния

RESTful сервер не должен отслеживать, хранить и тем более использовать в работе текущую контекстную информацию о клиенте. Клиент должен взять эту задачу на себя. Другими словами: не заставляйте сервер помнить состояние мобильного устройства, использующего API.

Давайте представим, что мы разрабатываем социальное приложение. Хороший пример, где разработчик мог совершить ошибку это предоставление вызова API, который позволяет мобильному устройству установить последний прочитанный элемент в ленте. Вызов API, обычно возвращающий ленту (назовем его /feed), теперь будет возвращать элементы, которые новее установленного. Звучит умно, не правда ли? Вы «оптимизировали» обмен данными между клиентом и сервером? А вот и нет.

Что может пойти не так в приведенном случае, так это то, что если ваш пользователь использует сервис с двух или трех устройств, то, когда одно из них устанавливает последний прочитанный элемент, то остальные не смогут загрузить элементы ленты, прочитанные на других устройствах ранее.

Независимость от состояния означает, что данные, возвращаемые определенным вызовом API, не должны зависеть от вызовов, сделанных ранее.

Правильный способ оптимизации данного вызова – использование заголовка HTTP If-Modified-Since. Но обсудим это позже.

Клиент же со своей стороны, может (должен) помнить параметры, сгенерированные на сервере при обращении к нему, и использовать их для последующих вызовов API, если потребуется.

Кэшируемая и многоуровневая архитектура

Второй принцип заключается в предоставлении клиенту информации о том, что ответ сервера может быть кэширован на определенный период времени и использоваться повторно без новых запросов к серверу. Этим клиентом может быть как само мобильное устройство, так и промежуточный прокси сервер. Подробнее о кэшировании будет сказано ниже.

Клиент – серверное разделение и единый интерфейс

RESTful сервер должен прятать от клиента как можно больше деталей своей реализации. Клиенту не следует знать о том, какая СУБД используется на сервере или сколько серверов в данный момент обрабатывают запросы и прочие подобные вещи. Организация правильного разделения функций важна для масштабирования, если ваш проект начнёт быстро набирать популярность.

Это, пожалуй три самых важных принципа, которым нужно следовать в ходе разработки RESTful сервера.

Документирование

как мобильное приложение взаимодействует с сервером. paper documents content. как мобильное приложение взаимодействует с сервером фото. как мобильное приложение взаимодействует с сервером-paper documents content. картинка как мобильное приложение взаимодействует с сервером. картинка paper documents content.

Худшая документация, которую может написать разработчик сервера — это длинный, однообразный список вызовов API с описанием параметров и возвращаемых данных. Главная проблема такого подхода заключается в том, что внесение изменений в сервер и формат возвращаемых данных по мере развития проекта становится кошмаром.

Первым шагом мы рекомендуем подумать об основных, высокоуровневых структурах данных (моделях), которыми оперирует ваше приложение. Затем подумайте над действиями, которые можно произвести над этими компонентами. Документация по foursquare API — хороший пример, который стоит изучить перед тем как начать писать свою. Данное API имеет набор высокоуровневых объектов, таких как места, пользователи и тому подобное. Также у них есть набор действий, которые можно произвести над этими объектами. Поскольку вы знаете высокоуровневые объекты и действия над ними в вашем продукте, создание структуры вызовов API становится проще и понятней. Например, для добавления нового места логично будет вызвать метод наподобие /venues/add

Документируйте все высокоуровневые объекты. Затем документируйте запросы и ответы на них, используя эти высокоуровневые объекты вместо простых типов данных. Вместо того, чтобы писать “Этот вызов возвращает три строковых поля, первое содержит id, второе имя, а третье описание” пишите “Этот вызов возвращает структуру (модель), описывающую место”.

Поддержка старых версий API

как мобильное приложение взаимодействует с сервером. tohwrench. как мобильное приложение взаимодействует с сервером фото. как мобильное приложение взаимодействует с сервером-tohwrench. картинка как мобильное приложение взаимодействует с сервером. картинка tohwrench.

До появления мобильных приложений, в эпоху Web 2.0 создание разных версий API не было проблемой. И клиент (JavaScript/AJAX front-end) и сервер разворачивались одновременно. Потребители (ваши клиенты) всегда использовали самую последнюю версию клиентского ПО для доступа к системе. Поскольку вы — единственная компания, разрабатывающая как клиентскую так и серверную часть, вы полностью контролируете то как используется ваш API и изменения в нем всегда сразу же применялись в клиентской части. К сожалению это невозможно с клиентскими приложениями, написанными под разные платформы. Вы можете развернуть API версии 2, считая что все будет отлично, однако это приведет к неработоспособности приложений под iOS, использующих старую версию. Поскольку ещё могут быть пользователи, использующие такие приложения несмотря на то, что вы выложили обновленную версию в App Store. Вам всегда надо быть готовым к разделению вашего API на версии и к прекращению поддержки некоторых из них как только это потребуется. Однако поддерживайте каждую версию своего API не менее трех месяцев.

Парадигма разделения на версии через URL

Первое решение — это разделение с использованием URL.
api.example.com/v1/feeds будет использоваться версией 1 iOS приложения тогда как
api.example.com/v2/feeds будет использоваться версией 2.
Несмотря на то, что звучит это все неплохо, вы не сможете продолжать создание копий вашего серверного кода для каждого изменения в формате возвращаемых данных. Мы рекомендуем использование такого подхода только в случае глобальных изменений в API.

Парадигма разделения на версии через модель

Выше мы показали как документировать ваши структуры данных (модели). Рассматривайте эту документацию как контракт между разработчиками серверной и клиентской частей. Вам не следует вносить изменения в модели без изменения версии. Это значит, что в предыдущем случае должно быть две модели №1 и №2.
Поведение модели №1 остается таким же, как это было оговорено в документации.

Кэширование

как мобильное приложение взаимодействует с сервером. cache. как мобильное приложение взаимодействует с сервером фото. как мобильное приложение взаимодействует с сервером-cache. картинка как мобильное приложение взаимодействует с сервером. картинка cache.

Переходим к кэшированию. Кэширование, по мнению многих, – преимущественно клиентская задача (или задача промежуточного прокси). Однако, при разработке серверной части ценой небольших усилий вы можете сделать ваш API полностью отвечающим требованиям промежуточных, кэширующих прокси. Это значит, что вы получите бесплатную балансировку нагрузки с их стороны. Все что нужно описано в 13-й главе спецификации HTTP.

Два главных принципа, которым мы вам рекомендуем следовать это:

В любом клиент-серверном приложении сервер — заслуживающий доверия источник информации. Когда вы загружаете ресурс (страницу или ответ) с API сервера, сервер отправляет клиенту, кроме всего прочего, некоторые дополнительные “подсказки” как клиент может кэшировать полученный ресурс. Сервер авторитетно указывает клиенту когда срок действия кэшированной информации истекает. Эти подсказки могут быть отправлены как программно, так и через настройку сервера. Модель срока действия обычно реализуется через настройку конфигурации сервера, в то время как модель валидности требует программной реализации силами разработчика серверной части. Именно разработчик должен решить, когда использовать валидность, а когда срок действия исходя из типа возвращаемого ресурса. Модель срока действия обычно используется когда сервер может однозначно определить как долго тот или иной ресурс будет действительным. Модель валидности используется для всех остальных случаев.

Модель срока действия

Давайте рассмотрим распространенную конфигурацию кэширования. Если вы используете nginx, у вас наверняка есть в конфиге нечто подобное:

\.(jpg|gif|png|ico|jpeg|css|swf)$ <
expires 7d;
>

nginx переводит эти настройки в соответствующий заголовок HTTP. В данном случае сервер отправляет поле “Expires” или “Cache-Control: max-age=n” в заголовке для всех изображений и рассчитывает на то, что клиент закэширует их на 7 дней. Это значит, что вам не нужно будет запрашивать эти же данные в течение 7-ми последующих дней. Каждый из распространенных браузеров (и промежуточных прокси) учитывает этот заголовок и работает как ожидается. К сожалению большинство Open Source фреймворков кэширования изображений для iOS, включая популярный SDWebImage, используют встроенный механизм кэширования, просто удаляющий изображения после n дней. Проблема заключается в том, что такие фреймворки не соответствуют модели валидности.

Модель валидности

Поддержка на стороне клиента

На самом деле под iOS, если вы используете MKNetworkKit, то он делает всю работу автоматически.

Но для разработчиков под Android и Windows Phone мы распишем подробно, как это следует реализовывать.
Модель валидности кэша использует заголовки HTTP: ETag и Last-Modified. Реализация для клиентской части при этом проще, чем для серверной. Если вы получили ETag с ресурсом, когда вы делаете второй запрос на получение его же, отправьте ETag в поле “IF-NONE-MATCH” заголовка. Аналогично, если вы получили “Last-Modified” с ресурсом, отправьте его в поле “IF-MODIFIED-SINCE” заголовка в последующих запросах. Сервер же со своей стороны сам решит когда использовать “ETag”, а когда “Last-Modified”.

Реализация модели срока действия проста. Просто рассчитайте дату окончания срока действия на основе полей заголовка, “Expires” или “Cache-Control: max-age-n” и очистите кэш при наступлении этой даты.

Реализация на стороне сервера

Использование ETag

ETag обычно рассчитывается на сервере с использованием алгоритмов хэширования. (Большинство серверных языков высокого уровня, таких как Java/C#/Scala обладают средствами хэширования объектов). Перед формированием ответа сервер должен рассчитать хэш объекта и добавить его в поле заголовка ETag. Теперь, если клиент действительно отправил IF-NONE-MATCH в запросе и данный ETag равен тому, что вы рассчитали, отправьте 304 Not Modified. Иначе сформируйте ответ и отправьте его с новым ETag.

Использование Last-Modified

Реализация использования Last-Modified не совсем проста. Давайте представим что в нашем API есть вызов, возвращающий список друзей.

Когда вы используете ETag, вы вычисляете хэш массива друзей. При использовании Last-Modified вы должны отправлять дату последнего изменения этого ресурса. Поскольку этот ресурс представляет собой список, эта дата должна являть собой дату когда вы последний раз добавили нового друга. Это требует от разработчика организации хранения даты последнего изменения данных для каждого пользователя в базе. Немного сложнее чем ETag, но дает большое преимущество в плане производительности.
Когда клиент запрашивает ресурс первый раз, вы отправляете полный список друзей. Последующие запросы от клиента теперь будут иметь поле “IF-MODIFIED-SINCE” в заголовке. Ваш серверный код должен отправлять только список друзей, добавленных после указанной даты. Код обращения к базе до модификации был примерно таким:

после модификации стал таким:

Если запрос не вернет записей, отправляем 304 Not Modified. Таким образом, если у пользователя 300 друзей и только двое из них были добавлены недавно, то ответ будет содержать только две записи. Время обработки запроса сервером и затрачиваемые при этом ресурсы снижаются значительно.
Конечно это сильно упрощенный код. Разработчику добавится головной боли когда вы решите сделать поддержку удаления или блокирования друзей. Сервер должен быть способным отправлять подсказки, используя которые у клиента будет возможность сказать какие друзья были добавлены, а какие удалены. Эта техника требует дополнительных усилий при разработке серверной части.

Выбор модели кэширования

Итак. Это была непростая тема. Теперь мы попробуем подвести итоги и вывести базовые правила использования той или иной модели кэширования.

Другой способ (более простой в реализации, но немного хакерский), это использование “ошибки URL”. Когда в ответе есть URL аватара, надо сделать часть его динамичной. Так вместо представления URL как

Хэш должен меняться в случае когда пользователь меняет аватар. Вызов, отправляющий список друзей, теперь отправит модифицированные URL-ы для пользователей, сменивших свои аватары. Таким образом изменения в изображениях профиля будут распространяться практически моментально!
Если ваши серверные и клиентские приложения будут соответствовать практически устоявшимся стандартам кэширования, ваше iOS приложение и ваш продукт вообще будут просто “летать”.

В этой статье мы дали простое объяснение таких стандартов, которых подавляющее большинство разработчиков не придерживаются.

Источник

Разработка сервера мобильных клиентов

Обратная сторона мобильных клиентов — сервер.

Введение

Не открою секрета, что разработка мобильных приложений в тренде – этому способствует стремительное техническое развитие: мобильные устройства с каждым годом улучшаются по всем характеристикам и становятся доступнее для широкого круга людей. Почти каждый, кто имеет на руках мобильный гаджет (будь то смартфон, коммуникатор или планшет) пользуется приложениями: браузером, клиентом электронной почты и мгновенных сообщений, играми, бизнес или финансовыми программами. И зачастую от пользователей скрыто то, что многие из приложений взаимодействуют с удаленным сервером: обмениваются с ним данными через Интернет.
По роду деятельности (Java разработчик серверных приложений) мне в команде приходится разрабатывать сервера для мобильных клиентов (за последние 2 года участвовал в реализации 3-х таких проектов для зарубежных компаний). Определился набор Java-технологий для решения задач такого рода, который варьируется в зависимости от требований и целесообразности (другими словами — желания), благо свобода при выборе технологий позволяет экспериментировать. Сформировавшейся точкой зрения и опытом хотел бы поделиться с сообществом.

Требования

Особенностью является то, что формируются требования и для серверного, и для клиентского приложения, которые в ряде случаев взаимосвязаны. Для начала опишу базовые требования в контексте механизма обмена данными:
• кроссплатформенность клиента: зачастую важно обеспечить поддержку разных платформ — Android, iOS, Windows Phone и пр. Редко заказчик довольствуется одним видом устройств.
• быстродействие: должна обеспечиваться достаточная для workflow скорость работы, комфортный отклик на графическом интерфейсе пользователя;
• простота: чем проще API протокола, тем меньше времени уходит на реализацию и поддержку кода, тем меньше может быть квалификация разработчика;
• эффективность: чем сложнее реализация протокола, тем больше потребляется ресурсов мобильного устройства, которые ограничены.

Дополнительные требования зависят от специфики приложения:
• масштабируемость сервера – для SaaS, социальных приложений, где в идеале ожидается большой поток посетителей, это условие обязательно. Для бизнес приложений, где есть ограничения по числу пользователей или численность прогнозируется, данное свойство не требуется;
• интерактивность: ряд приложений нужно обеспечить механизмом нотификаций – сообщить приложению (пользователю) о наступлении определенных событий, передать сообщение пользователю. Данным свойством должна обладать, например, биржевая система или автоматический диспетчер такси.
• открытое API: предполагается, что сторонние разработчики могут воспользоваться функционалом системы посредством документированного протокола. Ведь клиентом может быть как мобильное, так и внешнее серверное приложение.
• другие требования…

Команда

Состав проектной команды для разработки системы в идеале может быть следующим:
• менеджер проекта: управляет, контролирует проект, напрямую взаимодействует с заказчиком;
• разработчик серверного приложения: разрабатывает сервер бизнес логики, базу данных, сетевой протокол;
• разработчик приложения администратора: разрабатывает Web приложение, пользовательский интерфейс для настройки и управления серверным приложением;
• разработчик клиентского приложения для Android;
• разработчик клиентского приложения для iOS;
• разработчик клиентского приложения для …
• тестировщик: тестирует приложение администратора и клиентские приложения.

Внимательный читатель заметит, что в случае написания серверного приложения с графическим интерфейсом, например, на HTML5, можно сэкономить. В этом случае не требуется разработка клиентских приложений – интерфейс пользователя предоставляет браузер. Данная статья не рассматривает такой случай, идет речь о разработке ”родных” (native) приложений для мобильных устройств.

Мне доводилось работать в команде с полным составом, но будет реалистами – не всегда человеческие ресурсы и бюджет позволяет собрать такую команду. И иногда роли приходится совмещать: менеджер проекта + разработчик серверного приложения, разработчик клиентского приложения + тестировщик.

Технологии, инструменты, библиотеки

Для разработки сервера мобильных клиентов обычно использую следующий стек “свободных” технологий:
• Apache Tomcat – контейнер сервлетов;
• MySQL – СУБД;
• Subversion – система версионного контроля;
• Maven – фреймворк для автоматизации сборки проектов;
• JUnit – обеспечит эффективность автоматического тестирования приложений;
• Apache Log4j – библиотека логгирования;
• Jenkins – система непрерывной интеграции;
• Hibernate – ORM (настройки, конфигурация в properties, xml файлах и в аннотациях);
• hibernate-generic-dao – реализация DAO от Google, реализует основные методы для работы с данными базы данных, упрощает реализацию фильтрации и сортировки в методах;
• Spring – реализация аутентификации и авторизации (security), контейнер сервисов и бинов (конфигурация в xml файлах и в аннотациях), используем также при создании тестов.

В зависимости от специфики системы и требований к ней использую один из 2-ух вариантов реализации протокола обмена данными.
Когда требуются кроссплатформенность, быстродействие, простота, эффективность, масштабируемость, открытое API, то беру Jersey – реализацию Web-сервисов REST (RESTful Web services). Эта библиотека позволяет использовать сериализацию данных в формате JSON или(и) XML. Конфигурация REST ведется посредством аннотаций. Для обмена с мобильными устройствами взят формат JSON по причине того, что имеет более простую реализацию на стороне клиента (по этой причине не используем “классические” Web-сервисы), генерируется меньший объем трафика. Jersey позволяет настроиться на наиболее подходящий “вид” JSON.
В ином случае, если необходимы кроссплатформенность, высокое быстродействие, простота, эффективность, интерактивность, то беру
• Apache MINA – framework для создания сетевых приложений,
• Google protobuf – библиотека кодирования и декодирования структурированных данных. Структура данных определяется заголовочными файлами *.proto, компилятор генерирует из них Java классы (также есть возможность генерации для других языков программирования: C++, Objective-C и т. д., что обеспечивает свойство кроссплатформенности);
• java.util.concurrent – используем стандартный пакет.
Данный вариант может масшабироваться, но на это требуется закладываться на этапе проектирования на уровне архитектуры, учитывая бизнес логику.

Рассмотрим гипотетическую задачу на примере выбора технологий для реального SaaS сервиса – “Аукцион услуг “Аукнем”, который позволяет людям сформировать заказ на выполнение требуемых услуг или работ, а организациям в свою очередь оставить для них свои предложения. Берем все базовые требования по умолчанию. Ввиду того, что регистрация в этой системе свободная и бесплатная, то однозначно к ним требуется добавить масштабируемость. А что на счет интерактивности? Было бы здорово сообщать подрядчикам (исполнителям) о создании новых заказов, а заказчиков информировать о поступивших предложениях в тот же миг в приложении, а не только по электронной почте. На основания этого возьмем для реализации Apache MINA, Google protobuf. Смотрим следующее свойство — открытое API. Сервис общедоступный, потому предположим, что внешние разработчики могут проявить интерес к интеграции с ним. Постойте! Не все так просто. Протокол на базе Apache MINA достаточно сильно зависит от реализации и интеграция без знания нюансов отнюдь не прозрачна. В такой ситуации придется взвесить, какой фактор важнее и сделать выбор.

Источник

Как мобильное приложение взаимодействует с сервером

Это самый простой метод. Устройство запрашивает список блюд у сервера и сервер отсылает весь список целиком. Каждый раз список приходит весь. Не сортированный.

Пример запроса: null, либо “<>”

Достоинства:

Недостатки:

Область применения:

Подход 2: Синхронизируется только обновленное

Устройство запрашивает список блюд, обновленный с предыдущей синхронизации. Список приходит отсортированный по “updated” в порядке возрастания (необязательно, но удобно). Устройство хранит значение “updated” у самого последнего присланного блюда и при следующем запросе шлет его серверу в параметре “lastUpdated”. Сервер присылает список блюд, которые новее “lastUpdated” (updated > lastUpdated). При первом запросе на сервер “lastUpdated” = null.

На схеме: “last_updated” – значение, которое хранится на устройстве. Обычно на устройстве создается отдельная таблица для хранения этих значений “last_updated” по каждой сущности (блюда, города, организации и т.п.)

Этот подход годится для синхронизации простых линейных списков, у которых правила прихода на устройство одинаковые для всех устройств. Для более избирательной синхронизации см “Подход 5: Синхронизация со знанием того, что уже есть на устройстве”.

Обычно этот подход перекрывает большинство нужд. На устройство приходят только новые данные, синхронизироваться можно хоть каждую минуту – трафик будет небольшой. Однако тут возникают проблемы, связанные с ограничениями мобильных устройств. Это память и процессор.

Подход 3: Синхронизация порциями

У мобильных устройств мало оперативной памяти. Если в справочнике 3000 блюд, то парсинг большой json строки от сервера в объекты на устройстве может вызвать нехватку памяти. В этом случае приложение либо аварийно завершится, либо не сохранит эти 3000 блюд. Но даже если устройство смогло переварить такую строку, то производительность приложения в моменты синхронизации в фоне будет низкая (лаги интерфейса, не плавная прокрутка и т.п.) Поэтому необходимо запрашивать список более мелкими порциями.

Для этого устройство передает еще один параметр (“amount”), который определяет размер порции. Список присылается обязательно отсортированный по полю “updated” по возрастанию. Устройство, аналогично предыдущему подходу, запоминает значение “updated” у последней присланной сущности и передает его в поле “lastUpdated”. Если сервер прислал ровно это же количество сущностей, то устройство продолжает синхронизацию и снова делает запрос, но уже с обновленным “lastUpdated”. Если сервер прислал меньше сущностей, это значит, больше новых данных у него нет, и синхронизация завершается.

На схеме: “last_updated” и “amount” – значения, которые хранятся в мобильном приложении. “last_item” – последняя присланная с сервера сущность (блюдо). Именно новее этого значения будет запрошен следующий список.

Достоинства:

Недостатки:

Подход 4: Корректная синхронизация порциями

В предыдущем подходе возможна ситуация, что если в таблице есть 250 блюд с одинаковым “updated” (например, “2013-01-10 12:34:56”) и размер порции равен 100, то придут только первые 100 записей. Остальные 150 будут отсечены жестким условием (updated > lastUpdated). Почему так произойдет? При запросе первых 100 записей lastUpdated установится в “2013-01-10 12:34:56”, и следующий запрос будет иметь условие (updated > “2013-01-10 12:34:56”). Не поможет даже смягчение условия (updated >= “2013-01-10 12:34:56”), потому что устройство тогда будет бесконечно запрашивать первые 100 записей.

Ситуация с одинаковым “updated” не настолько редкая. Например, при импорте данных из текстового файла поле “updated” было выставлено в NOW(). Импорт файла с тысячами строк может занять меньше секунды. Может случиться и так, что весь справочник будет иметь одинаковый “updated”.

Чтобы это исправить надо использовать какое-то поле блюда, которое было бы уникальным хотя бы в пределах одного момента (“updated”). Поле “id” уникально вообще по всей таблице, так что следует дополнительно в синхронизации использовать именно его.

Итого, реализация этого подхода выглядит так. Сервер отдает список отсортированный по “updated” и “id”, а устройства запрашивают данные с помощью “lastUpdated” и нового параметра “lastId“. У сервера условие выборки усложняется: ((updated > lastUpdated) OR (updated = lastUpdated and id > lastId)).

На схеме: “last_updated”, “last_id” и “amount” – значения, которые хранятся в мобильном приложении. “last_item” – последняя присланная с сервера сущность (блюдо). Именно новее этого значения будет запрошен следующий список.

Подход 5: Синхронизация со знанием того, что уже есть на устройстве

Предыдущие подходы не учитывают факта, что сервер в реальности не знает насколько успешно данные сохранились на устройстве. Устройство могло просто не сохранить часть данных из-за невыясненных ошибок. Поэтому неплохо было бы получать от устройства подтверждение, что все (или не все) блюда сохранились.

Кроме этого, пользователь приложения может так настроить приложение, что ему нужна будет только часть данных. Например, пользователь хочет синхронизировать блюда только из 2 городов из 10. Описанными выше синхронизациями этого не добиться.

Идея подхода следующая. Сервер хранит у себя (в отдельной таблице “stored_item_list”) информацию о том, какие блюда есть на устройстве. Это может быть просто список пар “id – updated”. В этой таблице хранятся все списки пар “id – updated” блюд для всех устройств.

Информацию об имеющихся на устройстве блюдах (список пар “id – updated“) устройство отсылает серверу вместе с запросом на синхронизацию. При запросе сервер проверяет то, какие блюда должны быть на устройстве и какие есть сейчас. После этого на устройство отсылается разница.

Как сервер определяет, какие блюда должны быть на устройстве? В простейшем случае сервер делает запрос, который возвратит ему список пар “id – updated” всех блюд (например, SELECT id, updated FROM dishes). На схеме это делает “WhatShouldBeOnDeviceMethod()” метод. В этом недостаток подхода – серверу приходится вычислять (порой делая тяжелые sql-запросы), что должно быть на устройстве.

Как сервер определяет какие блюда есть на устройстве? Он делает запрос в таблицу “stored_item_list” по этому устройству и получает список пар “id – updated”.

Анализируя эти два списка, сервер решает, что следует послать на устройство, а что – удалить. На схеме это “delta_item_list”. Поэтому в запросе нет “lastUpdated” и “lastId”, их задачу выполняют пары “id – updated”.

Как сервер узнает об имеющихся на устройстве блюдах? В запросе к серверу добавляется новый параметр “items”, который содержит список id блюд, которые были присланы на устройство в прошлой синхронизации (“device_last_stored_item_list”). Конечно, можно отсылать список id всех блюд, которые есть на устройстве, и не усложнять алгоритм. Но если на устройстве 3000 блюд и они будут каждый раз все отсылаться, то расходы трафика будут очень велики. В подавляющем количестве синхронизаций параметр “items” будет пустой.

Сервер должен постоянно обновлять у себя “stored_item_list” данными, которые пришли с устройства в параметре “items”.

Следует реализовать механизм очистки серверных данных в stored_item_list. Например, после переустановки приложения на устройстве сервер будет считать, что на устройстве все еще актуальные данные. Поэтому при установке приложения устройство должно как-то проинформировать сервер чтобы он очистил stored_item_list по этому устройству. В нашем приложении мы посылаем дополнительный параметр “clearCache” = 1 в этом случае.

Заключение

Сводная таблица по характеристикам этих подходов:

ПодходОбъем трафика(5 – большой)Трудоемкость разработки(5 – высокая)Использование памяти устройства(5 – высокое)Корректность данных на устройстве(5 – высокая)Можно выделить конкретное устройство
1Синхронизируется всегда все5155нет
2Синхронизируется только обновленное1253нет
3Синхронизация порциями1313нет
4Корректная синхронизация порциями1313нет
5Синхронизация со знанием того, что уже есть на устройстве2525да

“Корректность данных на устройстве” – это вероятность того, что на устройстве есть все данные, которые отсылались сервером. В случае подходов №1 и №5 есть 100% уверенность, что устройство имеет все данные, которые нужны. В остальных случаях такой гарантии нет. Это не говорит о том, что остальные подходы использовать нельзя. Просто если на устройстве часть данных пропадет, то исправить это с сервера (а тем более узнать про это на стороне сервера) не получится.

Возможно, при наличии безлимитных тарифов на интернет и бесплатного wifi проблема ограничения трафика, генерируемого мобильным приложением, станет менее актуальна. Но пока приходится идти на всякие ухищрения, придумывать более “умные” подходы, которые позволяют снизить сетевые расходы и увеличить производительность приложений. Не всегда это работает. Порой бывает “чем проще – тем лучше”, зависит от ситуации. Надеюсь, из этой статьи можно подобрать подход, который пригодится.

В интернете на удивление мало описаний синхронизации сервера и мобильных устройств. Притом, что приложений, работающих по такой схеме, много. Для интересующихся пара ссылок:

как мобильное приложение взаимодействует с сервером. blog img. как мобильное приложение взаимодействует с сервером фото. как мобильное приложение взаимодействует с сервером-blog img. картинка как мобильное приложение взаимодействует с сервером. картинка blog img.

как мобильное приложение взаимодействует с сервером. defolt 2. как мобильное приложение взаимодействует с сервером фото. как мобильное приложение взаимодействует с сервером-defolt 2. картинка как мобильное приложение взаимодействует с сервером. картинка defolt 2.

как мобильное приложение взаимодействует с сервером. defolt 2. как мобильное приложение взаимодействует с сервером фото. как мобильное приложение взаимодействует с сервером-defolt 2. картинка как мобильное приложение взаимодействует с сервером. картинка defolt 2.

как мобильное приложение взаимодействует с сервером. 7. как мобильное приложение взаимодействует с сервером фото. как мобильное приложение взаимодействует с сервером-7. картинка как мобильное приложение взаимодействует с сервером. картинка 7.

как мобильное приложение взаимодействует с сервером. 600xNx16 1.jpg.pagespeed.ic . pxW6ByG9Z 1 1. как мобильное приложение взаимодействует с сервером фото. как мобильное приложение взаимодействует с сервером-600xNx16 1.jpg.pagespeed.ic . pxW6ByG9Z 1 1. картинка как мобильное приложение взаимодействует с сервером. картинка 600xNx16 1.jpg.pagespeed.ic . pxW6ByG9Z 1 1.

как мобильное приложение взаимодействует с сервером. 17 %D0%B8%D0%BA%D0%BE%D0%BD%D0%BA%D0%B0. как мобильное приложение взаимодействует с сервером фото. как мобильное приложение взаимодействует с сервером-17 %D0%B8%D0%BA%D0%BE%D0%BD%D0%BA%D0%B0. картинка как мобильное приложение взаимодействует с сервером. картинка 17 %D0%B8%D0%BA%D0%BE%D0%BD%D0%BA%D0%B0.

г. Барнаул, пр. Калинина, 116/44

Энтерра очень успешно выполнила для нас два проекта.

Первым было приложение для программы маркировки серийных продуктов, написанное на VB6. Хотя это приложение и не было сложным, мы выдвигали ряд специфичных требований к работе, связанных с высокой отказоустойчивостью системы, что, конечно, было бы недостижимо для менее квалифицированной команды разработчиков.

Моим вторым проектом с Энтеррой стало JSP/Tomcat/PostGreSQL/Linux серверное приложение для производства тестов кодирования и декодирования и анализа результатов этих тестов. Несмотря на довольно сложные требования, Энтерра выполнила потрясающую работу, показав превосходное качество архитектуры и кодирования.Эти проекты были инициированы не новичками: первый разрабатывался для многоструктурного производственного предприятия, а второй стал продуктом, реализуемым по ранее наработанным каналам.

По правде говоря, сомневаюсь, что вам было бы интересно получить рекомендацию от только что образовавшейся фирмы, которая работала с Энтеррой, просто потому, что у новичков не с чем сравнивать.Скажу вам откровенно, мне не раз приходилось лично руководить командами разработчиков в США и даже несколькими зарубежными командами (дистанционно), но Энтерра – стала лучшей командой, с которой мне только приходилось работать.

В отношении работы с клиентами, сотрудничая с ними, у меня никогда не возникало сложностей. Хочу отметить, что мне довелось лично общаться с Дмитрием Старостенковым в фазе оценки проекта и подписания соглашений и с проект-менеджером в фазе разработки.В отношении технического профессионализма, могу с уверенностью рекомендовать Энтерру в следующих областях: Java, JSP, Visual Basic 6, PostGreSQL (и SQL в общем), Windows API, Linux и Linux scripting, XML, Tomcat и ODBC. И что определенно отличает Энтерру от других зарубежных команд, с которыми мне доводилось работать, так это их особое внимание к вопросам качества кода и тестирования. Именно поэтому я непременно обращусь к Энтерре снова с практически любым IT проектом.Не знаю, какой опыт вы имеете в разработке. Если он внушителен, просто проигнорируйте следующее, а если вы не очень давно в этой сфере, прочтите несколько советов на будущее:Старайтесь закладывать свой бюджет на разработку на несколько процентов больше предварительно оцененного, поскольку нужно быть готовым к дополнительной работе над деталями, которые вы просто не можете предвидеть и просчитать сразу.

Если вы намерены твердо придерживаться четкого графика, заранее позаботьтесь о том, чтобы Энтерра знала, что время – ваш главный приоритет, это поможет достичь успеха. Но это касается только моего опыта, а я никогда не разрабатывал что-либо, кроме софта, в рамках ограниченного срока.Знайте также, что вам нужно будет предоставить Энтерре все текстовые записи на английском для своего приложения.

Это не сложно, но нужно учесть заранее, поскольку даже если ваше приложение сейчас ориентировано на Американское общество, вы должны смотреть в лицо современным тенденциям глобализации и планировать интернационализацию своего проекта.

Из 12 участников только трое оказались способными произвести нечто стоящее в рамках выделенного времени. Вам троим я адресую это письмо.

Проблема была не из простых, и, если бы мне самому довелось быть на вашем месте, думаю, я был бы крайне озадачен и испуган выдвинутыми требованиями. Если бы я мог наградить призовым грантом каждого из вас! Но, к сожалению, «победитель» должен быть один!Решения, которые вы, Энтерра, смогли найти, совершенно поразительны и тысячу раз превзошли все мои ожидания!

Даже невооруженным взглядом видно, эксперты этой команды обладают незаурядными навыками Java и объектно-ориентированного программирования. И несмотря на довольно сухое комментирование, я совершенно потрясен проделанной вами работой: кто бы это ни делал, он бесспортно чречвычайно талантлив.

Я верю, что эта команда – наш лучший партнер, и надеюсь на долгое и очень плодотворное сотрудничество. Безмерно рад работать с такими профессионалами. И еще раз спасибо за вашу великолепную работу.

Мне бы хотелось письменно поблагодарить Энтерру за квалифицированную помощь.

Мы разрабатывали прототип системы ExpressCLERK и наняли некоторых «специалистов» для создания интерфейса. К сожалению, они оказались совсем не такими профессионалами, какими себя позиционировали.

Нам пришлось потратить тысячи долларов и потерять несколько месяцев, а приложение так и осталось неработающим.В попытке выжить мы расстались с горе-разработчиками и наняли Энтерру для исправления работы. В тот момент мы уже имели один негативный опыт.

Так вот, Джереми Грувз (представитель Энтерры в США) взял нас за руку и вел с нами все переговоры в то время, как команда специалистов Энтерры пыталась отчаянно спасти наш проект. К нашему огромному удовлетворению, работа была выполнена через три недели (как и было обещано) – точно в срок и четко в рамках выделенного бюджета.

Не было ни оправданий, ни проволочек, ни изменений в цене.Мы продолжили работать с Энтеррой над другими элементами нашей системы и вполне довольны и расценками, и уровнем коммуникаций, и графиком работ.

Мы, в ExpressCLERK, очень рады поделиться своим опытом работы с Энтеррой и рекомендовать Энтерру для профессиональных контактов и программирования на самом высоком уровне.

Мы работаем с Энтеррой вот уже 2 года над созданием принципиально новой CMS структуры и расширением нашей старой CMS.

Затевая этот проект, мы были в позиции новичков, поскольку это наш первый опыт обращения к зарубежным программистам вообще и разработки новой большой CMS системы в частности.

Все, что я хочу сказать ниже, относится исключительно к опыту работы с Энтеррой над CMS системой (поскольку это наш единственный проект вместе).Итак, что мы можем сказать из своего опыта: Энтерра – довольно профессиональный партнер для оффшорного программирования.

В самом начале проекта мы предполагали, что, открывая для себя эту совершенно новую область, ввязываемся в авантюру, сопряженную с большими рисками, но Энтерра поразила нас своим высококлассным менеджментом, прекрасной командной работой, и конечно, высоким качеством программирования.Вам, должно быть, известен Закон Хеопса: Все проекты занимают больше времени, чем было запланировано. Этот закон случился с нами за все время работы с Энтеррой всего однажды в работе над самым первым маленьким проектом, да и то, только потому, что мы тогда еще не освоили рабочий регламент друг друга и не скоординировали прием выполненной задачи вовремя.

Все последующие проекты были выполнены точно по расписанию, а наш последний проект – программирование web-клиента – был окончен даже на 4 недели раньше запланированного.И конечно, вам следует знать, если вы предоставите максимально подробные спецификации на свой проект, то Энтерра рассчитает вам точную стоимость вашего проекта, и это будет именна та сумма, которую нужно заплатить. Они не из тех, кто пытается выжать из вас больше, обнаруживая в конце проекта: «О, извините, мы неверно посчитали, на ваш проект потребуется на 500 часов больше!» и все такое.Мы определенно еще обратимся к Энтерре, поскольку до сих пор были полностью удовлетворены работой этой команды.И в конце позвольте дать важный совет тому, кто собирается воспользоваться услугами оффшорных программистов: заморские программисты настолько хороши, насколько хорош менеджер проекта на вашей стороне. Для достижения реального успеха вам понадобится действительно толковый человек на месте – вот ключ к успеху в оффшорном программировании.

Энтерра предоставила для нашего проекта удивительно компетентную и профессиональную команду.

За время реализации проекта мы лишь пару раз столкнулись с необходимостью внести коррективы (и это при том, что наши требования не были достаточно сформулированы на начальном этапе).

Мы встретили поразительный интерес и внимание к нашему проекту; если с нашей стороны возникали просьбы внести какие-то изменения, то они производились немедленно и очень оперативно. Это позволило закончить проект точно в срок.Надо сказать, что доверием к этой компании мы прониклись с самого начала общения, буквально с первого вопроса, который от них получили.

Они оказались очень компетентными специалистами и поразили нас глубоким пониманием сути нашего проекта уже на первых порах.Мы определенно будем продолжать работать с ними над новыми проектами.

Огромное вам спасибо! Я абсолютно удовлетворен результатом моего проекта.

Мои требования были реализованы на 120%. Команда Энтерры привнесла в мой проект дополнительный (очень интересный) функционал, который я даже и не мечтал иметь в составе моей системы.

У них поразительная техническая подготовка и навыки ноу-хау, и они применили все это на моем проекте, окончив его точно в срок. Общение с командой было всегда очень эффективным и дружелюбным. Я даже мог время от времени общаться с ними по ICQ.

Я готов рекомендовать Энтерру всем без исключения и непременно буду работать с ними сам над новыми проектами.

Это был просто экстремальный проект, который нужно было реализовать в кратчайшие сроки и со множеством серьезных преобразований «в последний момент».

И несмотря на все это, Энтерра выполнила проект в срок и оправдала все наши ожидания. Каждый этап работы Энтерра выполняла точно по графику, как и ожидалось.

Вся документация и код, которые они нам предоставили, были тщательно исследованы нашими специалистами на предмет соответствия нашим стандартам, и результат нас очень порадовал.

Команда Энтерры показала прекрасный пример ведения переговоров и использования внутренних инструментов для ежедневного мониторинга состояния проекта. Это позволило идти в ногу с графиком работ и оперативно решать все возникающие по ходу проекта вопросы.

Мы оцениваем их работу очень высоко – как слаженную и профессиональную. Они прекрасно справились с нашими сложными и весьма привередливыми требованиями.Мы планируем продолжить работать с Энтеррой и далее, поскольку видим в ней надежного и перспективного партнера.

Я был и остаюсь очень впечатлен компанией Энтерра и порекомендовал их другим людям.

Они завершили проект точно в срок, эффективно обработали несколько существенных изменений в рамках проекта, и с ними было легко общаться несмотря на разницу в часовых поясах и языках.

Я просмотрел несколько компаний здесь в штате, и как оказалось, я только выиграл, наняв Энтерру, помимо того, что затратил значительно меньше средств. После завершения проекта, я давал код на инспекцию ведущим программистам в Остине, штат Техас.

Все они сказали, что код написан хорошо, и были очень удивлены тому, что я получил за мои деньги. Я слышал много страшных историй от людей, которые нанимали зарубежные команды, и я благодарен тому, что нанял Энтерру. Мне их очень рекомендовали, и они полностью превзошли мои ожидания.

Команда Дмитрия взялась за реализацию очень сложного Java приложения для моего проекта.В действительности, в начале проекта я и сам не был до конца уверен в том, что кто-то сможет осилить подобное.

Этот проект был поистине вызовом, содержа в себе 3 различные системы (задачи). И хоть каждая из них и была вполне под силу профессионалу, все вместе они требовали экстра-усилий и внимания, не говоря уже о первоклассной технической подготовке в области Java/JSP.

Они не просто выполнили этот проект, но еще и сдали его раньше срока, сумев попутно решить еще множество стихийно возникших проблем и задач.

Если вам нужны разработчики экстра-класса, то вы – как раз по адресу. Энтерра все время развивается и совершенствуется. Они способны заглядывать вперед и предвидеть все возможные технические аспекты, без труда преодолевая любые сложности интеграции или реализации.

В течение последних 9 месяцев Энтерра показала потрясающе высокие стандарты в области разработки и поддержки программного обеспечения.

Наши требования были далеки от четкого представления результата, но Энтерра смогла оперативно проанализировать суть проекта и предложить замечательное техническое решение, которое даже превзошло наши ожидания.

У нас сразу же возникло чувство твердой уверенности в том, что эта компания способна понять все наши специфичные технические требования и нужды и реализовать качественную систему в четко обозначенные сроки.И мы были поистине потрясены скоростью и качеством ответов на наши запросы. Прекрасная командная работа.

Источник

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *