Среда для синхронизации универсальных объектов с версиями в распределенной среде
3 Чешский технический университет в Праге Факультет электротехники Факультет вычислительной техники Дипломная работа Структура синхронизации общих версий сущностей в распределенной среде Bc. Владимир Покорный Руководитель: Ing. Учебная программа Мартина Мудра: Открытая информатика, Магистерская область: Программная инженерия 25 мая 2016 г.
5 в Благодарности Я хотел бы поблагодарить моего руководителя Ing. Мартину Мудру за все советы и комментарии.
7 vii Декларация Заявляю, что представляемая диссертация подготовлена мною самостоятельно и что я перечислил все использованные источники информации в соответствии с Методической инструкцией по соблюдению этических принципов при подготовке выпускных работ вуза. В Праге
9 Резюме Эта диссертация посвящена разработке и реализации структуры для общей синхронизации объектов данных, включая создание и ведение истории их версий. Фреймворк использует клиент-серверную архитектуру. Упор делается на продолжение синхронизации в случае сбоя подключения к серверу, используя прямое клиентское подключение (peer-to-peer). Этот тезис также касается обнаружения и разрешения конфликтов в обоих режимах связи (клиент-сервер и одноранговая сеть). Также включен пример реализации использования платформы для упрощенной синхронизации файлов. Аннотация Эта работа посвящена разработке и внедрению структуры, позволяющей синхронизировать общие объекты данных, включая их версии. Фреймворк использует клиент-серверную архитектуру и упор сделан на возможность продолжения синхронизации через прямое соединение между клиентами (одноранговое соединение) в случае сбоя соединения с сервером. В то же время в данной работе речь идет о выявлении и способе разрешения конфликтов воба режима связи (клиент-сервер и одноранговая). Частью этой работы является пример реализации использования этой платформы для упрощенной синхронизации файлов. икс
11 Содержание 1 Введение Цель работы Анализ Требования Функциональные требования фреймворка Нефункциональные требования фреймворка Функциональные требования примера реализации Нефункциональные требования примера реализации Отрицательное определение Существующие решения Dropbox LAN sync BitTorrent Sync BitTorrent Syncthing Другие подобные сервисы Резюме Поиск клиентов Обнаружение WCF Связь в распределенной среде Режим одноранговой связи Клиент в роли сервера WCF Размещение на собственном хостинге Алгоритмы сопоставления Синхронизация сущностей и конфликты Возникновение конфликтов Разрешение конфликтов версий Последняя загрузка актуальна Автоматическое разрешение Разрешение конфликтов между пользователями Конфликты сущностей Разрешение конфликтов Управление версиями в распределенной среде Управление версиями Вектор Принцип работы xi
12 xii СОДЕРЖАНИЕ Правила работы Преимущества и недостатки Конфликты в распределенной среде Ручное разрешение конфликтов Автоматическое разрешение конфликтов Технические решения Инверсия среды управления Средство ведения журнала базы данных Решение пользовательского интерфейса Дизайн Базовое описание архитектуры Хранение данных для синхронизации файлов Поиск клиентов Механизмы для синхронизация данных Идентификация объекта Версии объектов Группы объектов Модель связи между клиентами Связь Переключение между режимами связи клиент-сервер и одноранговая Связь Выбор клиентов для одноранговой связи Разрешение конфликтов Протокол связи Интерфейс связи Архитектура системы Архитектура сервера Back-end архитектура клиента Интерфейсная архитектура клиента -end Описание основных операций синхронизации Создание нового объекта или версии на клиенте Создание нового объекта или версии на сервере Получение новогосущность на клиенте Получение сущности на основе запроса от клиента База данных Серверная база Таблицы для конкретной реализации фреймворка Клиентская база данных Таблица для конкретной реализации фреймворка Пользовательский интерфейс Реализация Программное обеспечение для разработки Программное обеспечение для работы системы Структура проекта
13 СОДЕРЖАНИЕ xiii 4.4 Отделение фреймворка от синхронизации определенных сущностей Сторона сервера Сторона клиента Другие определенные интерфейсы Тестирование Тестирование через синхронизацию файлов Тестовая среда Тестовое оборудование Тестовое оборудование Тестовые сценарии и результаты тестирования Тестирование поиска клиентов Результат тестирования Тестирование примера приложения с помощью пользователей Результат первой итерации Результат второй итерации Результат третьей итерации Тест развертывания фреймворка Результат теста Заключение Сложность переключения между режимами связи Возможности дальнейшего улучшения системы Безопасность системы Оптимизация коммуникации Связь между клиентами Векторы версий Дальнейшие улучшения фреймворка Расширение функциональные возможности примера синхронизации файлов Ссылки 53 A Список используемых ярлыков 57 B Инструкции по использованию фреймворка 59 B.1 Ввод в эксплуатацию сервера B.2 Ввод в эксплуатацию клиента B.3 Использование NHibernate и AutoMapper C Инструкции по запуску системы синхронизации файлов 63 C. 1 Развертывание сервера C.2 Запуск клиента D Список тесты 65 D.1 Инициализация приложения D.2 Поиск клиента D.3 Базовая синхронизация
14 xiv СОДЕРЖАНИЕ D.4 Переключение между режимами связи D.5 Функциональность пула клиентов E Документация по интерфейсу связи 69 E.1 Методы интерфейса одноранговой связи E.2 Методы интерфейса связи с сервером F Скриншоты примеров приложений 71 G Содержание прилагаемый DVD 73
15 Список изображений 2.1 Схема связи в одноранговом режиме Схема связи в режимеклиент в роли сервера Схема загрузки новой версии и включения ее в историю Схема возникновения конфликта с точки зрения истории версий Схема разрешения конфликта установкой текущей версии Схема разрешения конфликта созданием новой сущности Схема конфликта разрешение путем включения в историю Схема обновления вектора версионности Базовое деление фреймворка Разделение частей фреймворка Поиск клиентов Схема выгрузки истории сущностей на сервер Диаграмма истории сущностей, выгруженных на сервер Загрузка сущностей в одноранговых режим одноранговой связи Структура сообщения SOAP с сущностью, содержащей файл Диаграмма архитектуры сервера Диаграмма архитектуры клиента Диаграмма архитектуры MVVM Диаграмма последовательности создания новой версии сущности на клиенте Диаграмма последовательности создания новой версии версии сущности на сервер Схема последовательности получения новых сущностей на клиенте Схема последовательности получения сущности по запросу от клиента Схема базы данных сервера Схема базы данных клиента Дизайн пользовательского интерфейса главного окна приложения Dia gram компоненты серверной части Схема компонентов клиентской части Конфигурация подключения устройства для тестирования Конфигурация подключения устройства для тестирования обоих режимов связи одновременно Конфигурация сетевого подключения устройства для тестирования поиска клиента F.1 Экран инициализации приложения F.2 Главное приложение экран xv
16 xvi СПИСОК ИЗОБРАЖЕНИЙ F.3 Зеленый значок уведомления с открытым всплывающим окном F.4 Синий значок уведомления G.1 Содержимое прикрепленного DVD
17 Список таблиц 2.1 Сравнение существующих решений Сравнение методов поиска клиентов Список устройств тестирования Список инструментов тестирования E.1 Список методов интерфейса связи для одноранговой связи E.2 Список методов интерфейса связи сервера xvii
18 xviii СПИСОК ТАБЛИЦ
19 Глава 1Введение Синхронизация данных в последнее время все чаще используется обычными пользователями. Он в основном используется в режиме связи клиент-сервер. Основной причиной может быть расширение ассортимента облачных хранилищ, которые используются как для хранения файлов, так и, например, в случае Microsoft или Google, для хранения контактов, календарей и т. д. Для пользователей такой подход имеет два принципиальных преимущества. Многие пользователи владеют более чем одним устройством, и одним из преимуществ синхронизации является обеспечение доступности одних и тех же данных на всех этих устройствах. Это могут быть различные стационарные компьютеры и ноутбуки, либо смартфоны и планшеты. Вторым преимуществом синхронизации является обеспечение резервного копирования данных, что оценит пользователь, например, в случае повреждения диска, потери устройства или просто при переходе со старого телефона на новую модель. В этих случаях пользователь не только не потеряет эти данные, но и когда синхронизация будет завершена на новом устройстве, все эти данные будут доступны. Вся эта синхронизация происходит полностью автоматически, поэтому пользователю не нужно ни о чем беспокоиться. Синхронизация может происходить между клиентским устройством и сервером (например, с облачным хранилищем) или через прямое соединение между отдельными устройствами (одноранговая сеть) без использования какого-либо центрального элемента. Оба этих метода имеют свои преимущества и недостатки. 1.1 Цель работы Целью данной работы является разработка и реализация фреймворка, который позволит по мере необходимости комбинировать оба режима связи (клиент-сервер и одноранговый) и, таким образом, использовать преимущества обоих. Тип синхронизируемых сущностей будет зависеть от конкретного использования этой платформы, но будут поддерживаться все сущности, которые можно передавать по сети с помощью потока данных. Пример реализации с использованием этой платформы будет синхронизировать файлы в папке. Из-засложность этого метода синхронизации гарантирует возможность использования фреймворка даже для более простых объектов, таких как телефонные контакты. Использование фреймворка будет заключаться в реализации доступа к конкретным сущностям (чтение и запись). Эти сущности могут храниться, например, в базе данных. Сама структура сама заботится о логике синхронизации, включая управление версиями отдельных объектов и взаимодействие в обоих режимах. Для правильного функционирования фреймворка все равно необходимо будет произвести настройки в конфигурационных файлах. 1
20 ГЛАВА 1. ВВЕДЕНИЕ 2
21 Глава 2 Анализ В этой главе в первую очередь указываются функциональные и нефункциональные требования. За этим разделом следует описание существующих решений, имеющих хотя бы несколько схожий функционал с рассматриваемым в данной работе. Кроме того, есть разделы, описывающие способы поиска клиентов для связи в распределенной среде и возможные способы связи в этой среде. Существенная часть анализа посвящена описанию синхронизации общих сущностей, включая создание и разрешение конфликтов. Важной частью является описание того, как управление версиями работает в распределенной среде, потому что решить, какая версия новее, может быть не совсем просто. Заключение анализа посвящено техническим решениям, которые могут подойти для развития данной системы. 2.1 Требования В этом подразделе перечислены функциональные и нефункциональные требования, разделенные на требования, относящиеся к фреймворку (логика синхронизации), и требования, относящиеся к примерной реализации использования этого фреймворка (синхронизация файлов). Требования относятся к системе в целом, т.е. серверная и клиентская стороны Функциональные требования к фреймворку Система сможет синхронизировать сущности в режиме клиент-серверного взаимодействия. Система позволит создавать новые объекты, новые версии объектов или удалять их на сервере.сущности. Клиенты будут постоянно загружать текущие сущности с сервера. Система сможет синхронизировать сущности в режиме одноранговой связи. Клиент разрешит локальное создание новых сущностей, новых версий сущностей или удаление сущностей. Клиенты будут постоянно загружать текущие объекты с какого-либо другого клиента. Система сможет версионировать сущности (создавать их историю). 3
22 ГЛАВА 2. АНАЛИЗ В системе предусмотрена возможность автоматического перехода в режим одноранговой синхронизации в случае обрыва соединения. Система сможет автоматически переходить в режим клиент-серверной синхронизации при восстановлении соединения после сбоя, и одновременно выгружать на сервер историю версий созданных сущностей. Система будет хранить информацию о других клиентах для целей установления связи в пиринговом режиме. Система позволит группировать объекты в группы, где каждый объект сможет принадлежать к нескольким из этих групп. Система сможет обнаруживать и разрешать конфликты. Клиент сможет искать доступных клиентов Нефункциональные требования фреймворка Система будет создана в виде фреймворка. То есть фреймворк позаботится о логике синхронизации, включая связь между всеми участвующими устройствами. Конкретная реализация, использующая структуру, будет использоваться для доступа к определенным типам сущностей (например, для чтения и записи в файл). Система будет работать под управлением операционной системы Microsoft Windows 7. Исходные коды и документация к ним будут на английском языке. Никакие лицензионные библиотеки использоваться не будут, что потребует публикации всего приложения под лицензией этой библиотеки Функциональные требования для примера реализации Клиент позволит синхронизировать файлы в выбранной папке на жестком диске. В этой папке клиент будет фиксировать события создания, изменения, удаления и переименования файла, а затем соответствующим образом создавать новые версии.сущности. В эту папку также будут загружены текущие файлы с сервера или другого клиента. Клиент позволит разрешать конфликты, возникающие в режиме связи клиент-сервер. Клиент позволит добавлять и удалять выбранные файлы в группы Нефункциональные требования к реализации примера Клиент будет использовать графический интерфейс пользователя. Клиент будет на английском языке. 4
23 2.2. СУЩЕСТВУЮЩИЕ РЕШЕНИЯ Отрицательное определение В рамках этой работы не будут рассматриваться какие-либо формы системной безопасности. Таким образом, сохраненные данные и сетевое общение никак не будут зашифрованы. Система не будет учитывать существование учетных записей пользователей, поэтому аутентификация или авторизация выполняться не будут, поэтому синхронизация правильных сущностей будет происходить только на основе определенных групп сущностей. 2.2 Существующие решения При исследовании существующих решений выяснилось, что некоторые сервисы предлагают схожую функциональность, но ни в одном из этих случаев это была не библиотека, а всегда полноценный продукт. Ближайшая функциональность предоставляется Dropbox, который включает в себя функцию синхронизации по локальной сети, но не работает без функционального подключения к Интернету. С другой стороны, две другие службы BitTorrent Sync и Syncthing работают без хранения данных на сервере. Эти сервисы, включая их функциональные возможности, более подробно описаны в следующих подразделах Dropbox Синхронизация по локальной сети Dropbox — один из самых известных сервисов облачного хранения файлов. Чтобы использовать его, вы можете использовать веб-интерфейс или один из множества клиентов как для настольных, так и для мобильных устройств. Клиенты для настольных ПК позволяют выполнять полную синхронизацию файлов. В качестве дополнительной функции они предлагают синхронизацию по локальной сети, которая позволяет синхронизировать файлы напрямую с компьютерами в локальной сети[1], что ускоряет передачу данных. Хотя все клиенты находятся в одной сети, подключение кИнтернет, так как клиенты получают информацию об измененных данных с сервера и только потом пытаются загрузить файл с устройства в локальной сети. Чтобы синхронизация по локальной сети работала, все клиенты должны находиться в одной подсети или на одном широковещательном адресе, иначе клиенты не смогут найти друг друга. В результате эта функция предназначена только для ускорения передачи данных, когда связь по локальной сети быстрее, чем через Интернет. Эта функция определенно не решает возможности синхронизации данных при недоступности сервера или интернет-соединения. свою работу и, следовательно, пропускает server[2] . Следовательно, нет центрального элемента, который решает, какая версия файла является единственной текущей, но каждый отдельный клиент должен сам поддерживать эту информацию. В результате велика вероятность возникновения конфликтов, с которыми каждому клиенту приходится разбираться самому. Эта программа основана на протоколе BitTorrent, поверх которого построена полная синхронизация между клиентами, включая расширенные функции, такие как обмен файлами или управление версиями. Поскольку это проприетарное программное обеспечение, информация о том, как именно оно работает, отсутствует. 5
24 ГЛАВА 2. АНАЛИЗ BitTorrent BitTorrent — это коммуникационный протокол для обмена файлами в одноранговых сетях[3]. Он в основном используется для загрузки больших файлов. Чтобы начать передачу, вам нужен клиент BitTorrent и торрент-файл, содержащий метаданные о конкретных файлах для передачи, включая адрес трекера. Впоследствии клиент присоединяется к рою (рой — это все пиры, совместно использующие данный торрент). Сама загрузка происходит таким образом, что файл делится намножество мелких частей, каждую из которых можно загрузить с другого пира в рое и тем самым добиться максимально возможной скорости передачи. Как только одноранговый узел загрузил некоторые части, он может предложить их другим одноранговым узлам для загрузки. Поиск клиентов может осуществляться несколькими способами: Локальное обнаружение Поиск пиров в той же локальной сети с использованием многоадресного запроса. Трекер Это сервер, содержащий информацию о том, какой файл хранится (т.е. IP-адреса пиров). PEX (одноранговый обмен) Одноранговые узлы, подключенные к одному и тому же рою, напрямую обмениваются информацией о других одноранговых узлах в рое. DHT (Распределенная хеш-таблица) Информация о расположении файлов на отдельных клиентах не хранится централизованно, а распределяется по разным узлам. Затем из каждого узла DHT можно получить доступ к нескольким другим узлам DHT. Однако для подключения к какому-либо первому узлу DHT необходимо знать его адрес. Syncthing Как и BitTorrent Sync, Syncthing[4] также подходит для синхронизации файлов. Функционал этих двух конкурирующих программ очень похож. Существенная разница заключается в том, что Syncthing использует свои собственные протоколы, которые задокументированы на его веб-сайте. Второе важное отличие заключается в том, что исходный код этой программы находится под открытой лицензией Mozilla Public License Version 2.0. Поиск клиентов происходит двумя способами: либо с помощью протокола Global Discovery, когда клиент опрашивает сервер каждые 30 минут, либо с помощью протокола Local Discovery, когда клиент отправляет широковещательный запрос в локальную сеть каждые 30 секунд. Обе эти опции можно отключить. Обмен данными происходит через одноранговое соединение. Предполагая, что два работающих устройства не могут видеть друг друга (например, они находятся за NAT), Syncthing использует протокол ретрансляции и серверы ретрансляции, обеспечивающие обмен данными. Сам обмен данными указан в протоколе блочного обмена.Другие аналогичные сервисы Помимо вышеперечисленных сервисов, существуют и другие, предлагающие аналогичный функционал. Например, SpiderOak (облачное хранилище, в основном ориентированное на защиту конфиденциальности данных) 6
25 2.3. ПОИСК КЛИЕНТОВ содержит или содержит функцию LAN Sync[5], которая должна служить для ускорения передачи данных в локальной сети, как и в случае с LAN-синхронизацией Dropbox. Однако эта функция нигде не документирована, о ней есть только упоминания[6]. Еще один интересный сервис — Cubby, который, как и Dropbox, представляет собой обычное облачное хранилище, но предлагает функцию DirectSync[7], позволяющую отключить синхронизацию некоторых папок с облаком и синхронизировать свои данные только в одноранговой сети. — режим одноранговой связи. Однако в этом случае пользователь всегда должен выбирать, в каком режиме будет работать Cubby.Резюме Как уже упоминалось, ни одно из исследованных существующих решений не предлагает той же функциональности, которая рассматривается в данной работе. Для наглядности результирующее сравнение ключевого функционала этих решений показано в таблице 2.1. Таблица 2.1: Сравнение существующих решений Можно ли синхронизировать в режиме клиент-сервер? Может ли он синхронизироваться в одноранговом режиме? Может ли он автоматически переключать синхронизацию между клиент-сервером и P2P? Это библиотека или фреймворк? Это решение с открытым исходным кодом? Синхронизация Dropbox по локальной сети BitTorrent Syncthing SpiderOak Cubby Да Нет Нет Да Да Да Частично 1 Да Да Неизвестно Нет Нет Нет Неизвестно Да Нет Нет Нет Нет Нет Нет Нет Нет Да Нет Нет 2.3 Поиск клиентов Первоочередной задачей является установление связи между отдельными клиентами важно найти этих клиентов. На основе анализа существующих решений было установлено, что существует два основных метода поиска клиентов. Первый способ — это различные протоколы обнаружения, с помощью которых клиенты пытаются найти себя,чаще всего с использованием какого-либо многоадресного или широковещательного запроса. Недостаток этого метода в том, что он не может найти всех клиентов из-за различных устройств, которые блокируют отправку мультикастовых и широковещательных запросов. Второй метод основан на сервере, который известен всем клиентам и, что наиболее важно, имеет полную базу данных клиентов, включая их адреса. С этого сервера клиенты могут скачать текущую 1 Только для обмена данными. Список файлов всегда извлекается с сервера. 7
26 ГЛАВА 2. АНАЛИЗ списка доступных клиентов. Доступность клиентов, обнаруженных таким образом, не гарантируется, поскольку они могут находиться за устройствами с поддержкой NAT. Клиенты, найденные этими двумя способами, могут быть сохранены в памяти и эта память также может быть использована в дальнейшем при поиске клиентов. Недостатком данных в этой памяти является то, что они могут быть неактуальны. Этот метод может подойти, если ни один из клиентов не был найден двумя предыдущими способами. Сравнение этих трех методов поиска показано в таблице 2.2. Таблица 2.2: Сравнение методов поиска клиентов Сервер Многоадресная рассылка Локальная база данных Находит ли она всех клиентов? Да Нет Нет Работает без подключения к серверу? Нет Да Да Будет ли он получать текущие данные клиента? Да 2 Да Нет WCF Discovery Framework WCF непосредственно для обнаружения включает поддержку[8]. В частности, он использует протокол WS-Discovery, который использует стандарты веб-сервисов[9], в частности SOAP-over-UDP. Этот протокол использует многоадресный адрес и обменивается данными через UDP на порту. Преимуществом является обнаружение ближайших клиентов без использования какой-либо третьей стороны. Недостатком являются ограниченные возможности обнаружения других клиентов в результате использования многоадресных сообщений, которым не нужно проходить через маршрутизатор, поэтому даже если два устройства находятся рядом друг с другом и в одной сети, это не означает, они могут найти друг друга. Еще одна проблема, котораяможет появиться, это блокировка связи брандмауэром. Чтобы устранить эти недостатки, эта структура включает возможность предоставления службы под названием Discovery Proxy, которая служит хранилищем всех активных служб (клиентов). Преимущество в том, что методы хранения и запроса клиентов нужно реализовывать вручную, поэтому ничто не мешает, например, использовать базу данных. Еще одной важной особенностью является то, что использование этого прокси тесно связано с многоадресным поиском, поэтому все происходит полностью автоматически. В частности, это означает, что когда клиент предоставляет услугу, он уведомляет прокси-службу. Это также означает, что когда клиент вызывает метод обнаружения службы, платформа будет пытаться использовать как многоадресную рассылку, так и прокси-службу. Большим недостатком этого подхода является поиск всех служб, что, учитывая, что каждый клиент предоставляет одну службу, означает поиск всех активных клиентов в Интернете. Однако для синхронизации файлов необходимо найти только тех клиентов, у которых есть такие же файлы. 2.4 Общение в распределенной среде В стандартном режиме клиент-серверного взаимодействия роли всех устройств фиксированы. Связь всегда инициируется клиентом, который отправляет запрос на сервер. Сервер имеет известный фиксированный URL. 2 Предполагая, что клиент не менял сеть 8
с момента потери связи с сервером
27 2.4. СВЯЗЬ В РАСПРЕДЕЛЕННОЙ СРЕДЕ В распределенной среде предлагаются два возможных метода связи[10][11]: Каждый клиент устанавливает соединение с другими клиентами и пытается войти с ними в синхронное состояние. Один клиент выбирается в качестве сервера, а остальные клиенты взаимодействуют только с этим временным сервером. Однако в обоих случаях важно знать, по крайней мере, о некоторых других клиентах, доступных для связи Режим одноранговой связи В режиме одноранговой связиpeer, все клиенты пытаются перейти в синхронное состояние, общаясь с другими клиентами (рис. 2.1). Это можно сделать двумя способами: Запрос-ответ Публикация-подписка При использовании метода запрос-ответ канал связи создается только на время одного запроса, а затем закрывается[12]. Преимуществом этого метода является небольшое количество открытых соединений, которое зависит только от количества обрабатываемых в данный момент запросов. Для получения новых данных необходимо периодически спрашивать других клиентов об изменениях. Второй метод работает по принципу публикации-подписки. При установлении связи между двумя клиентами эти клиенты регистрируются друг у друга, и если происходит какое-либо изменение сущности, эта информация рассылается всем зарегистрированным клиентам[13]. Клиенты, зарегистрированные таким образом, имеют постоянно открытый канал связи, поэтому их количество нужно как-то ограничивать, ведь в противном случае подключений было бы столько, сколько клиентов, участвующих в синхронизации. Рисунок 2.1: Схема связи в одноранговом режиме Режим связи клиент-сервер В случае использования этого режима все клиенты будут общаться абсолютно одинаково даже после перехода из режима связи клиент-сервер в режим распределенной Окружающая среда. 9
28 ГЛАВА 2. АНАЛИЗ Все, что им нужно будет сделать, это договориться о выборе временного сервера, а затем перенаправить связь на адрес этого вновь выбранного сервера (Рисунок 2.2). Сам выбор клиента в качестве сервера — самое сложное в этом режиме. Должен быть создан только один сервер, и поэтому все клиенты должны четко с этим согласиться. Крайне важно, чтобы выбранный таким образом сервер имел достаточное сетевое подключение и достаточно мощное оборудование. Проблема в том, что нет четкого выбора серверагарантировано. Любой временно выбранный сервер может отключиться в любой момент, после чего необходимо выбрать новый. Когда соединение с главным сервером впоследствии восстанавливается, все клиенты, выступавшие в роли сервера, должны позаботиться о загрузке сущностей на сервер. Рисунок 2.2: Диаграмма связи в режиме клиента в роли сервера с собственным размещением WCF По умолчанию службы развертываются на каком-либо веб-сервере, например на сервере информационных служб Интернета. Службы WCF спроектированы таким образом, что помимо сервера IIS их также можно запускать непосредственно в настольных приложениях или службах Windows[14]. Развертывание службы WCF непосредственно в приложении называется самостоятельным размещением и может использоваться для включения одноранговой связи Алгоритмы соответствия В некоторых случаях необходимо обеспечить консенсус (согласование) между всеми устройствами в системах, работающих в распределенной среде [15]. Для этой цели используются алгоритмы сопоставления, такие как Paxos[15]. Принцип этих алгоритмов заключается в том, что одни устройства отправляют предложение другим, и они могут его принять или отклонить. В случае принятия большинством это предложение объявляется решением. В случае предлагаемой системы можно было бы использовать любой из этих алгоритмов для разрешения конфликтов при общении без доступного сервера. Но эти алгоритмы требуют возможности связи между всеми устройствами и не учитывают их динамическое увеличение и уменьшение, поэтому при разрешении конфликта может возникнуть конфликт. Из-за этих особенностей использование этих алгоритмов не очень удобно. 10
29 2.5. СИНХРОНИЗАЦИЯ ОБЪЕКТОВ И КОНФЛИКТЫ 2.5 Синхронизация объектов и конфликты В общем, синхронизация — это ситуация, когда несколько событий происходят одновременно и необходимо обеспечить, чтобы все части системы находились в одном и том же состоянии или выполняли определенные операции в нужное время. . Так что естьбольше видов, например, в случае компьютерной синхронизации процессов или потоков. В случае сущностей это будет синхронизация данных. Целью синхронизации данных является достижение синхронного состояния сущностей[16][17], т.е. обеспечение согласованности данных отдельных сущностей на всех устройствах. Таким образом, когда сущность изменяется на одном устройстве, это изменение должно отражаться на всех остальных, участвующих в синхронизации. Устройства должны как можно быстрее переходить в синхронное состояние. Более простая ситуация возникает, если это односторонняя синхронизация, т.е. изменения происходят только на одном устройстве, а затем эти изменения отправляются на любое количество других устройств. Более сложная ситуация в случае двусторонней синхронизации, где из-за того, что достижение синхронного состояния в реальном времени зачастую невозможно либо с точки зрения скорости, либо недоступности сетевого соединения, могут возникать конфликты . Эти конфликты возникают, когда один объект изменяется в двух или более местах одновременно (или во время недоступного соединения). В этом случае трудно решить, какая версия актуальна. Этот тезис касается двусторонней синхронизации данных, поэтому следующие подразделы описывают создание и разрешение конфликтов Создание конфликтов Прежде всего, необходимо каким-то образом обнаруживать конфликты. Это можно сделать, если каждый объект будет хранить свою собственную историю версий, а при загрузке новой версии объекта на сервер будет напрямую указано, в какую версию объекта загружаются эти данные (рис. 2.3). Когда две или более версий затем загружаются в одну конкретную версию, это означает, что возник конфликт (рис. 2.4). Рисунок 2.3: Схема загрузки новой версии и включения ее в историю Другой тип, более сложный для обнаружения, — это конфликт между различными сущностями. Эти конфликты возникают снова при загрузке новой версии,но они возникают не из-за загрузки двух версий в одну конкретную, а из-за какого-то другого ограничения данной системы. Примером может служить случай, когда не может быть двух автомобилей с одинаковыми номерными знаками. Другой типичный пример — файловая система, в которой два файла с одинаковыми именами не могут находиться в одной папке. В случае с файлами вы можете попасть в конфликт, просто переименовав или переместив файл. 11
30 ГЛАВА 2. АНАЛИЗ Рисунок 2.4: Диаграмма возникновения конфликта с точки зрения истории версий Разрешение конфликтов версий В клиент-серверной среде решение о текущей версии принимает сервер, который может сделать это в несколькими способами[16]. В одноранговой коммуникации принять решение о текущей версии сложнее, потому что в этот момент нет родителя, за которым последнее слово. Но в этой работе существующий сервер рассматривается в фоновом режиме, поэтому клиенты могут дождаться, пока сервер станет доступен, и оставить за ним принятое решение. Как уже упоминалось, история версий (идентификатор версии объекта) может использоваться для обнаружения конфликта, а затем может быть сохранено время создания объекта для разрешения конфликта. Если сервер поддерживает только текущую версию сущности, то возможны следующие решения: Установить конфликтующую версию как текущую (рис. 2.5) Попытаться объединить обе версии Создать новую сущность и, таким образом, сохранить обе версии (рис. 2.6) Отбросить конфликтующую версию Рисунок 2.5: Диаграмма разрешения конфликтов путем установки текущей версии Но если сервер поддерживает историю сущностей (версионирование), то у него будет еще один вариант решения – включить конфликтующую версию в историю (Рисунок 2.7 ). Таким образом, пользователь не потеряет никаких данных и сможет вернуться к ним в любое время.Последняя загрузка актуальна.конфликтов нет, и если кто-то выложит новую версию, она будет считаться текущей. Проблема такого подхода заключается с одной стороны в потере данных, но более существенная проблема в том, что пользователь никак не узнает об этой потере. 12
31 2.5. СИНХРОНИЗАЦИЯ СУЩНОСТЕЙ И КОНФЛИКТОВ Рисунок 2.6: Схема разрешения конфликтов путем создания новой сущности Рисунок 2.7: Схема разрешения конфликтов путем включения в историю Автоматическое разрешение В некоторых случаях сервер может решить сам. Самый простой — сравнить, являются ли две сущности одинаковыми, что можно сделать с файлами, например, сравнив их хэш-код. Поэтому, если обе версии идентичны, не имеет значения, какая сущность выбрана в качестве текущей. Предполагая, что две версии не совпадают, идеальным решением для пользователя было бы объединить изменения из обеих сущностей, что можно сделать только в некоторых случаях. Обычно это возможно только для текстовых файлов, но только в том случае, если внутри этого файла нет конфликтующих изменений (например, различное редактирование одной и той же строки в каждом объекте). Есть готовые алгоритмы именно для этих целей и они используются, например, в системе управления версиями Git. Другим возможным решением является использование даты модификации объекта, где в качестве текущей версии принимается версия с наибольшим временем. Однако в этом случае возникает проблема асинхронности времени между клиентами и сервером. Таким образом, на эти данные можно полагаться только в том случае, если эти времена совпадают. Но если они расходятся (разный часовой пояс, летнее время, неверно настроенные минуты), то однозначно определить, какая версия была создана позже, не представляется возможным. Для гарантии работоспособности необходимо было бы организовать синхронизацию часов на всех устройствах. Если синхронное время не устроено на всех устройствах, единственное достоверное время — это время на сервере. Хотя, по его словам, можно контролировать и определять, что это за сущность.тока больше, но может быть решено не правильно. Не гарантируется, что объект, прибывший на сервер последним, действительно является самым новым. Этот объект мог быть создан когда-то в прошлом, но устройство не было подключено к Интернету до текущего момента. Так что это решение точно не подходит Разрешение конфликтов пользователем В случае разрешения конфликта пользователь разрешает серверу загружать все версии, а при обнаружении конфликта эта версия помечается как конфликтующая и пользователю предлагается 13
32 ГЛАВА 2. АНАЛИЗ разрешил ситуацию. Предлагаемые решения могут быть следующими: Замена текущей версии Включение в историю Отказ Сохранение обеих версий текущими (дублирование сущностей) Способ разрешения конфликта с помощью замены — пометить только что прибывшую версию как текущую. Первоначальная версия настоящим переносится в историю. Метод включения сущности в историю работает прямо противоположным образом, когда текущая версия сервера остается неизменной, а вновь поступившая версия включается в историю так, как если бы она была создана до текущей версии сервера. Если данная система позволяет это, пользователь может разрешить конфликт, отказавшись от вновь поступившей версии. Это очень легко разрешает конфликт, но за счет потери пользователем полной истории изменений сущности. Еще одна интересная возможность разрешить конфликт — поддерживать актуальность обоих объектов. Это достигается за счет создания на сервере совершенно новой сущности, не имеющей ничего общего с исходной. Однако простого дублирования может быть недостаточно из-за возможного конфликта между сущностями, поэтому, например, в случае файлов вновь созданный файл необходимо будет переименовать (обычно используется исходное имя с добавлением постфикса, например, числа или имя устройства) Конфликты сущностей В общем случае невозможно сказать, в каком случае возникают конфликты между сущностями. Эти конфликтысильно зависит от типа сущностей и ограничений данной системы. В некоторых случаях эти конфликты могут вообще не возникать, потому что объекты вообще не могут конфликтовать, например, галерея изображений, где не имеет значения, что два объекта имеют одинаковое имя. Однако, если объекты могут вступить в конфликт (два файла с одинаковым именем), его необходимо разрешить. Эти конфликты могут возникнуть в любой момент при загрузке нового объекта или новой версии. Разрешение конфликтов Существует два возможных подхода к разрешению конфликта между двумя объектами, когда либо сервер разрешает ситуацию автоматически, либо оставляет решение за пользователем. В этом случае очень хорошо могут работать автоматические решения, но об этом необходимо информировать пользователя. Невозможно четко определить, какое решение будет наиболее подходящим для данного объекта и системы. В некоторых ситуациях может быть лучше просто отклонить загрузку этой версии как неисправной. В других случаях в данный объект можно каким-то образом вмешаться, чтобы он не конфликтовал (например, уже упомянутое переименование файла). Описанные выше способы могут проходить как полностью автоматически, так и пользователю предлагается решить самому. Еще один слегка радикальный способ заключается в том, что вновь прибывшая версия остается без изменений, а вот с исходной надо что-то делать. Предлагаемые решения — это, например, переименование исходной версии или ее непосредственное удаление (операция замены). В большинстве случаев этот метод должен быть доступен только как опция пользователя. 14
33 2.6. УПРАВЛЕНИЕ ВЕРСИЯМИ В РАСПРЕДЕЛЕННОЙ СРЕДЕ 2.6 Управление версиями в распределенной среде В распределенной среде отсутствует центральный элемент принятия решений[17], поэтому каждый клиент должен иметь возможность определять порядок версий и в то же время обнаруживать возникновение конфликтов. . Этот принцип называется причинностью. Использование простых временных меток недостаточно.Хотя этот механизм может решить, какая версия была создана раньше, а какая позже, он не может определить, были ли некоторые версии созданы одновременно и, следовательно, конфликтуют друг с другом. Другим недостатком является необходимость обеспечения точной синхронизации времени на всех участвующих клиентах Вектор версий Механизм векторов версий решает обе упомянутые проблемы[18][19]. Другими словами, он способен определять порядок создания отдельных версий и в то же время обнаруживать одновременное создание двух версий (конфликт). Преимущество состоит в том, что ему не нужно время для работы, поэтому нет необходимости обеспечивать синхронизацию часов на клиентах. Как это работает Вектор версий содержит столько элементов, сколько реплик задействовано в синхронизации. Каждая позиция в этом векторе соответствует ровно одной конкретной реплике. Числовое значение в каждой позиции соответствует версии, произведенной соответствующей репликой. Каждая реплика поддерживает счетчик, который представляет номер последней версии, созданной этой репликой. Правила работы При первой инициализации все счетчики обнуляются, и векторы также обнуляются. Когда реплика изменяется локально, счетчик увеличивается на единицу, а соответствующая позиция данной реплики в векторе версий устанавливается равной текущему значению счетчика. Когда две реплики синхронизированы, обе реплики обновляют свой вектор версии: для каждой позиции (i) в векторе берется и используется большее значение из двух исходных векторов (VA и V B ). Формула расчета выглядит следующим образом V A [i] = V B [i] = max(v A [i], V B [i]). Сравнивая два вектора версий, можно с уверенностью определить, являются ли две версии идентичными, одновременными (конфликтующими) или определить порядок их создания (рис. 2.8). Идентичные версии, оба вектора должны иметь одинаковые значения в каждой позиции. Например. (5, 8, 9) = (5, 8, 9) Вектор V A возник раньше вектора V B для обоихвектора должны выполняться в каждой позиции V A [i] V B [i] и по крайней мере в одном случае должны выполняться V A [i]. точка, только векторы меняются местами. Например. (5, 41, 10) > (5, 8, 9) Текущая (конфликтующая) версия применяется, если векторы не удовлетворяют предыдущим правилам (хотя бы в одной позиции применяется V A [i] V B [j]). Например. (5, 8, 53) (45, 8, 9) Рисунок 2.8: Диаграмма обновления вектора версий. Цифры, выделенные жирным шрифтом, обозначают обновление, сделанное в векторе версии. Принцип управления версиями векторов аналогичен принципу управления версиями часов[20], при этом оба механизма используют векторы целых чисел, где эти числа всегда представляют один ресурс. Существенное отличие состоит в том, что часы версий используются для определения порядка, в котором происходят события, тогда как векторы версий полагаются только на состояние реплик и не определяют, произошло ли событие синхронизации. Механизм вектора версий, описанный выше, предполагал фиксированное количество реплик, что было бы проблемой. Эту проблему можно легко решить, сделав вектор динамически изменяемым, а его отдельные значения будут содержать пару значений, содержащих идентификатор клиента и номер версии вместо номера версии. Благодаря этому изменению он больше не будет (в зависимости от конкретного порядка элементов внутри) вектором. Вектор будет выглядеть следующим образом: [ClientA, 44], [ClientD, 81], [ClientC, 6] Преимущества и недостатки Преимущества: всегда можно безопасно решить, какая версия была первой и, возможно, обе версии конфликтуют. Возможность включения других новых клиентов в синхронизацию. Недостатки: интенсивное использование данных. По мере увеличения количества клиентов увеличивается и общая длина вектора. Эта длина больше не укорачивается впоследствии, потому что тогда было бы невозможно безопасно обнаружить последовательность и конфликты. 16
35 2.6. УПРАВЛЕНИЕ ВЕРСИЯМИ В РАСПРЕДЕЛЕННОЙ СРЕДЕ Этот недостаток можно решить путем удаления старых значений некоторых клиентов из вектора управления версиями. Таким образом, размер вектора уменьшится, но увеличится риск обнаружения ложных конфликтов. Недостатки версионных векторов решаются, например, механизмом Dotted Version Vector, целью которого является оптимизация метода отслеживания причинно-следственной связи в распределенном репозитории[21]. Конфликты в распределенной среде Таким образом, версионный вектор может служить механизм обнаружения конфликтов в распределенной среде. В момент обнаружения конфликта о нем знают только два клиента, между которыми он был обнаружен. Итак, на данный момент есть две возможности. Первый вариант — позволить всем клиентам дальше синхронизироваться и, таким образом, позволить этому конфликту постепенно распределяться между всеми доступными клиентами. Второй вариант — немедленное автоматическое разрешение конфликта. В этом втором случае другие клиенты вообще не будут знать о конфликте и будут только синхронизировать новую, неконфликтующую версию входящего объекта. Отбросить входящий объект. Создайте совершенно новую сущность и, таким образом, сохраните оба. Недостаток в том, что необходимо вести локально различную информацию о возникшем конфликте, в том числе: На какой версии сущности этот конфликт возник. С какой версией объекта он находится в конфликте. Как разрешился этот конфликт? Еще одна особенность этого метода заключается в том, что информация о конфликте распространяется среди доступных клиентов. Хотя у этого есть преимущество для пользователя, заключающееся в том, что конфликт может быть разрешен из любого места, недостатком является то, что каждый из двух клиентов может выбрать другое решение одновременно.конфликта и тем самым создать конфликт в разрешении конфликта. Далее необходимо распространить это решение среди других клиентов. 17
36 ГЛАВА 2. АНАЛИЗ Автоматическое разрешение конфликтов Способ автоматического разрешения конфликтов проще, поскольку не нужно создавать дополнительные механизмы распределения конфликтов и их разрешения, а используется уже существующий механизм создания новых версий сущностей и их синхронизации. . Чтобы этот механизм работал, необходимо принять решение о том, как конфликт будет разрешаться автоматически. Замена исходной сущности входящей сущностью или отбрасывание входящей сущности не является хорошим решением, поскольку пользователь может потерять важные данные. Лучшее решение — сохранить обе сущности, при этом одну нужно изменить, чтобы она не конфликтовала с другой (например, переименовать файл). 2.7 Технические решения Для всей этой системы необходимо было выбрать среду или фреймворк, которые позволили бы реализовать следующие моменты: Она была удобна как для клиентской, так и для серверной части системы. Он обеспечивает простую связь как в режиме клиент-сервер, так и в режиме одноранговой сети. Это позволило просто изменить тип объектов, которыми обмениваются в протоколе связи. Самым важным моментом было требование простой смены типа сущности, что должно гарантировать максимально простое использование этой системы в качестве фреймворка. В большинстве случаев при определении коммуникационного интерфейса необходимо напрямую указать все типы данных параметров и возвращаемых значений. В данном случае преимуществами зарекомендовала себя инфраструктура WCF, входящая в состав .net Framework начиная с версии 3.0[22] и позволяющая использовать универсальность в определении интерфейса[23], с помощью которой Возможно определить конкретный тип объекта только в конкретной реализации использования структуры синхронизации. Этот общий интерфейс является общимтолько до момента компиляции, поскольку результирующий сгенерированный коммуникационный интерфейс уже должен содержать фиксированные типы данных. Однако этого интерфейса вполне достаточно для целей данной системы. Фреймворк WCF также обеспечивает простое создание связи в режиме клиент-сервер (создание серверной и клиентской частей) и в одноранговом режиме[24]. Еще одним преимуществом является то, что WCF включает в себя протокол обнаружения, который позволяет искать клиентов для P2P-связи. По вышеуказанным причинам для реализации были выбраны .net Framework 4.5 и язык программирования C#[25][26]. В связи с этим выбором для пользовательского интерфейса была выбрана среда WPF. Эта структура упрощает создание пользовательского интерфейса и отделяет внешний вид (определенный в файле XAML) от функциональности[27] (код на C#). Инфраструктура Inversion of Control Инверсия управления (сокращенно IoC) — это принцип проектирования для создания приложений[28]. ]. Основной принцип заключается в ротации управления выполнением программы, когда пользовательский код вызывается из фреймворка и поэтому этот фреймворк должен иметь некоторые базовые знания об этом коде. 18
37 2.7. ТЕХНИЧЕСКИЕ РЕШЕНИЯ Это принцип, противоположный классическим библиотекам, где пользовательский код должен знать определенные методы внутри библиотеки, чтобы вызывать их. Частью инфраструктуры IoC является контейнер, который обеспечивает управление классами, когда он обеспечивает их создание, управление жизненным циклом и их настройку. Такой контейнер также использует шаблон проектирования внедрения зависимостей для разрешения зависимостей между классами[29]. Это позволяет уменьшить зависимости между отдельными компонентами и повысить модульность программы. Преимущество заключается в том, что программисту не нужно беспокоиться о том, откуда берутся эти компоненты, потому что об этом позаботится инфраструктура IoC. Принцип IoC также подходит для создания фреймворка синхронизации, поскольку онобрабатывать всю логику синхронизации, вызывая пользовательский код для выполнения только некоторых действий (в основном чтение и сохранение сущностей). Чтобы использовать контейнер IoC в .net Framework, можно использовать библиотеку Castle Windsor [30]. Этот контейнер позволяет настраивать с помощью XML-файла, поэтому перекомпиляция не требуется. Эта библиотека опубликована под лицензией Apache License Version 2.0, которая разрешает бесплатное использование[31] База данных Для хранения данных рекомендуется использовать реляционную базу данных. Для доступа к базе данных можно использовать инфраструктуру объектно-реляционного сопоставления (ORM), которая сопоставляет записи базы данных с объектами и наоборот. Частью этих фреймворков является также другой способ создания запросов, который устраняет зависимость от определенного диалекта SQL и, таким образом, позволяет упростить обмен реляционной базой данных. Поэтому можно использовать, например, Microsoft SQL Server на сервере. Однако на клиенте необходимо использовать локальную базу данных, которая будет служить только для данного приложения и не требует установки. Этим требованиям отвечает база данных SQLite[32], которая хранит данные в одном выбранном файле. База данных управляется через библиотеку SQLite, которая распространяется под лицензией Public domain, допускающей любое использование[33]. В .net Framework для ORM предлагается расширенный инструмент NHibernate[34] 4.0.4, который представляет собой порт фреймворка Hibernate, предназначенный для языка Java. NHibernate выпущен под лицензией GNU Lesser General Public License версии 2.1. В случае динамической компоновки библиотеки эта лицензия позволяет использовать в приложении любую лицензию[35]. Транзакции в NHibernate можно либо использовать вручную, вызывая соответствующие методы, либо воспользоваться преимуществами интеграции NHibernate с Castle Windsor и автоматически вызывать соответствующие методы для использования транзакций. Для этого автоматического вызова требуется vв коде отметьте методы доступа к БД с помощью инструмента Transaction attribute Logging В связи с функциональностью предлагаемой системы, где будут происходить различные сетевые коммуникации и одновременно будет запускаться несколько потоков для обработки разных запросов, будет необходимо использовать какой-либо инструмент ведения журнала для целей отладки программы. В .NET Framework для ведения журнала можно использовать Apache log4net[36], который является портом Apache log4j из языка Java. Преимуществом этой библиотеки является возможность входа в большой 19
38 ГЛАВА 2. АНАЛИЗ количество различных выходов, включая возможность создания собственного выхода. Эта библиотека распространяется под лицензией Apache License Version User Interface Solution. Поскольку эта работа включает в себя простой пример приложения для синхронизации файлов, и это приложение должно иметь пользовательский интерфейс, уместно выбрать архитектурный шаблон Model-View-ViewModel, созданный Microsoft[ 37] (сокращенно МВВМ). Основная цель этого шаблона — отделить разработку пользовательского интерфейса от разработки бизнес-логики. Чтобы лучше придерживаться этого шаблона, можно использовать MVVM Light Toolkit 5.2.0, цель которого — ускорить разработку приложений MVVM[38]. Эта библиотека распространяется по лицензии MIT, что позволяет использовать ее бесплатно[39]. 20
39 Глава 3 Проектирование Проектирование решения состоит из нескольких важных частей. Основа архитектуры, выбранный метод поиска других клиентов, механизмы, необходимые для синхронизации, выбранный протокол связи, архитектура системы, основные операции для синхронизации, дизайн базы данных и пользовательский интерфейс клиентского приложения для синхронизация файлов описана здесь. 3.1 Базовое описание архитектуры Framework будет состоять из нескольких отдельных частей. Наиболее абстрактное деление — на серверную и клиентскую части (рис. 3.1). Клиентская часть получитсянамного сложнее, потому что он будет действовать в нескольких ролях, в частности, как клиент, взаимодействующий с сервером и другим клиентом, или как сервер для другого клиента. База данных SQL Storage Server Client Client SQL Storage SQL Storage Рис. 3.1: Базовая структура инфраструктуры. Gears представляют собой клиентское или серверное приложение, включая коммуникационные интерфейсы. Синий соединитель представляет собой соединение в режиме связи клиент-сервер, а оранжевый соединитель представляет собой прямое соединение между клиентами. Еще одно разделение, как на сервере, так и на клиенте, происходит при разделении общей структуры синхронизации сущностей и фактического использования этой структуры для синхронизации файлов. 21
40 ГЛАВА 3. ДИЗАЙН Клиент Сервер Реализация Структура синхронизации Структура синхронизации Реализация Хранилище сущностей База данных Хранилище сущностей базы данных Клиент Рисунок 3.2: Разделение на части каркаса. Шестеренки представляют открытые коммуникационные интерфейсы. Вся коммуникация между двумя узлами (клиент-сервер или одноранговая сеть) будет осуществляться самим фреймворком, поэтому использование этого фреймворка будет заключаться в реализации фактического хранения и чтения данных, включая возможность выбора любое хранилище (рис. 3.2). Все данные, связанные с фреймворком и его конфигурацией, будут храниться в реляционной базе данных (это касается как серверной, так и клиентской части) Хранилище данных для синхронизации файлов Для хранения файлов на сервере и на клиента, а именно реляционную базу данных для хранения файловых метаданных и файловую систему хранения конкретных файловых данных. На стороне сервера будет создан простой репозиторий. Данные в этом хранилище будут физически находиться в выбранной папке на диске. Их имена будут некоторыми уникальными идентификаторами. Каждый файл будет иметь этот идентификатор, хранящийся всоответствующую запись среди метаданных в базе данных. На стороне клиента файлы также будут храниться непосредственно в выбранной папке на диске, но с той разницей, что это будет обычная папка, поэтому файлы будут там под своим именем и древовидная структура папок должна быть нормально сформировались здесь. При этом эта папка будет контролироваться, чтобы при изменении файла это изменение синхронизировалось. Каждый файл снова будет иметь соответствующую запись в базе данных, которая будет содержать путь к файлу. 3.2 Поиск клиентов Механизм поиска клиентов будет использовать всего три метода поиска (рис. 3.3). Первым способом будет прямое обнаружение с помощью многоадресной рассылки в локальной сети, которое будет осуществляться с помощью WCF Discovery, который сможет найти только ближайших клиентов в локальной сети. Недостатком является то, что не всегда может быть возможно найти все доступные устройства в одной сети, потому что на пути может быть маршрутизатор или какое-то другое устройство, которое не разрешает многоадресную рассылку. По этой причине будет доступен второй механизм, который будет использовать базу данных на сервере, содержащую IP-адреса клиентов. Это решение также позволит найти клиентов, которые могут легко установить P2P-соединение друг с другом, но находятся в другой сети. 22
41 3.3. МЕХАНИЗМЫ СИНХРОНИЗАЦИИ ДАННЫХ Клиент IPeerDiscovery ServerDiscovery MulticastDiscovery DatabaseDiscovery SQLite Server Клиент Клиент Рисунок 3.3: Обнаружение клиента показано с точки зрения используемых классов и интерфейсов. Третьим способом поиска будет небольшая база данных клиентов, хранящаяся непосредственно у клиента, которая будет содержать только релевантные записи (IP-адреса клиентов с одинаковыми файлами). Эта клиентская база данных будет обновляться с использованием двух предыдущих механизмов. Благодаря этой базе данных клиенты получат более полную информацию об IP-адресах отдельных устройств даже в случае сбоя подключения к серверу. При этом они смогут установить связьобмениваться этими знаниями с другими клиентами. 3.3 Механизмы синхронизации данных В этом подразделе описаны важные механизмы функционирования синхронизации, включая режимы синхронизации клиент-сервер и одноранговая сеть, а также их переключение. будет на сервере, всегда будет правильная текущая версия и клиенты будут постепенно обновлять свои объекты. Идентификатор сервера, сгенерированный серверной базой данных[40], будет использоваться для уникальной идентификации объектов. Клиенты заметят этот идентификатор как идентификатор сервера для каждого объекта в своей базе данных. В случае синхронизации между двумя клиентами ситуация сложнее. Предполагая, что клиент знает идентификатор сервера и просто обменивается данными с другим клиентом, это практически не проблема, поскольку это будут правильные данные (подтвержденные сервером). Более сложная ситуация будет, если сервер станет недоступен, а данные на клиенте изменятся. При нормальных обстоятельствах клиент отправляет эти данные на сервер, а сервер возвращает сгенерированный идентификатор. Однако в данном случае этого не будет, поэтому клиенту придется сгенерировать собственный глобально уникальный идентификатор[40] (GUID), на основе которого он будет обмениваться данными с другими клиентами. Генератор этого идентификатора содержится в 23
42 ГЛАВА 3. КОНСТРУКЦИЯ v.net Framework и разработан таким образом, что вероятность создания двух идентичных идентификаторов статистически незначительна[41]. По этой причине клиентам необходимо будет поддерживать идентификаторы GUID сущностей в дополнение к идентификатору сервера, если это необходимо. Рисунок 3.4: Схема загрузки истории объекта на сервер. Числа представляют собой идентификатор сервера, а строки 71c, 27f и a5b представляют собой идентификаторы GUID. Рисунок 3.5:Диаграмма истории сущностей, загруженных на сервер. Числа представляют собой идентификатор сервера, а строки 71c, 27f и a5b представляют собой идентификаторы GUID. При последующем восстановлении связи с сервером эти данные необходимо будет загрузить на сервер (рис. 3.4), поскольку, как уже было сказано, это единственное место, где обязательно будут правильные версии. Поскольку несколько клиентов могут одновременно пытаться загрузить одну и ту же версию, сервер также должен поддерживать этот GUID (рис. 3.5), и благодаря этому он сможет определить, что данная версия уже находится на сервере. Поэтому, как только клиент заполнил идентификатор сервера для всех сущностей, эти данные будут полностью синхронизированы с данными на сервере Версионирование сущностей Отметка времени CreateDate будет использоваться для правильного создания истории сущностей, которая будет определять создание время данной версии сущности. Для последующего восстановления истории достаточно будет отсортировать записи по этому тегу. Каждое устройство будет использовать свои собственные часы для создания этой временной последовательности, так как нельзя полагаться на время других устройств (сервера или клиентов) из-за несинхронизированных часов. Во время клиент-серверного и однорангового взаимодействия необходимо будет сравнить две версии и выяснить, какая из них новее, не конфликтуют ли они. Временные метки для этой цели не подходят именно из-за разной настройки часов на разных устройствах. При загрузке сущностей на сервер будет достаточно использовать данные о том, какая версия сущности была предыдущей (и, следовательно, где должна быть размещена загруженная версия). Чтобы одна и та же версия не загружалась несколько раз, необходимо будет проверить по GUID, не была ли она уже загружена. 24
43 3.3. МЕХАНИЗМЫ СИНХРОНИЗАЦИИ ДАННЫХ При прямом общении между клиентами необходимо будет использовать векторы версий, сравнивая которые можно четко определить какая версия новее или конфликтуют ли ониГруппы объектов Каждый объект будет принадлежать группе. Каждая такая группа будет называться пулом клиентов. Цель этих пулов клиентов будет состоять в том, чтобы сгруппировать объекты, которые так или иначе принадлежат друг другу, и, наоборот, разделить объекты, которые не принадлежат друг другу. Благодаря этому на клиенте можно будет синхронизировать только сущности в выбранных пулах клиентов. Механизм клиентских пулов также обеспечивает совместное использование объектов, позволяя назначать каждый объект нескольким клиентским пулам. В то же время благодаря этому механизму появится возможность фильтровать поиск клиентов, доступных для одноранговой связи Модель связи между клиентами В распределенной среде (когда сервер недоступен) будет использоваться одноранговый режим связи. Ни один клиент не возьмет на себя роль временного сервера, так как его однозначный выбор не гарантируется. Проблема в основном заключается в том, что каждый клиент может принадлежать к разным наборам пулов клиентов (к разным группам), но также каждый объект может принадлежать к разным наборам пулов клиентов. Таким образом, либо должен быть клиент, который будет обслуживать всех клиентов в роли сервера (он также должен будет обслуживать пулы клиентов, о которых он ничего не знает), либо для каждого пула клиентов должен быть выбран временный сервер ( в этом случае может случиться так, что несколько серверов будут обслуживать один и тот же объект). Для легкого переключения между клиент-серверным и одноранговым режимами связи будет удобно обеспечить схожесть интерфейсов связи. Отсюда следует, что в одноранговом режиме клиенты будут работать по принципу запрос-ответ, т. е. будут спрашивать других клиентов о новых сущностях, уже позаботятся о его синхронизации. В обоих режимах связи клиент сначала пытается загрузить данный объект всервер. Только после сбоя или успешного завершения загрузки этот объект будет предложен клиентом для синхронизации в режиме одноранговой связи. Новые сущности будут получены фреймворком с помощью периодического опроса. В режиме клиент-серверной связи клиент будет опрашивать сервер, а в режиме одноранговой связи во время запроса сначала будет выбран какой-либо другой активный клиент, а затем запрос будет выполняться на нем. Это приобретение новых организаций будет осуществляться в два этапа. На первом этапе будет сделан запрос на список новых сущностей (или версий). На втором этапе эти сущности будут постепенно загружаться. Эта процедура необходима для синхронизации более сложных объектов, таких как файлы. 25
44 ГЛАВА 3. ДИЗАЙН В режиме одноранговой связи функциональность платформы будет ограничена только синхронизацией объектов. Разрешение конфликтов, создание пула клиентов или назначение сущностей в пул клиентов будет работать только при работающем соединении с сервером Переключение между режимами связи клиент-сервер и одноранговой сети В нормальных условиях, когда доступно соединение с сервером , клиенты будут работать в режиме связи клиент-сервер. При обнаружении обрыва связи с сервером клиенты перейдут в режим одноранговой синхронизации. При последующем обнаружении соединения с сервером клиенты снова переключаются в режим связи клиент-сервер и пытаются загрузить на сервер все сущности, созданные в одноранговом режиме. Потеря соединения с сервером будет обнаружена просто по любому сбою запроса к серверу из-за тайм-аута или ошибки связи. Обнаружение повторного подключения к серверу будет производиться путем периодического запроса сервера, активен ли он уже (соединение восстанавливается, если этот запрос не завершается ошибкой) Выбор клиентов для одноранговой связи Всеклиент будет поддерживать список клиентов, подключенных к одному и тому же пулу клиентов. Клиент получает этот список при поиске клиентов (см. подраздел 3.2 Поиск клиентов). При получении списка новых сущностей будет использоваться отсортированный список активных клиентов, из которых по очереди будут браться отдельные клиенты. После завершения итерации этого списка будет создан новый список, известные клиенты будут опрошены, если они активны, и если да, то они будут добавлены в этот новый список. Затем этот список будет случайным образом перемешиваться. Эти шаги гарантируют, что все активные клиенты будут опрошены последовательно и что их порядок будет, по крайней мере, несколько случайным. (a) Запрос, у какого клиента есть объект (b) Различный быстрый ответ Рисунок 3.6: Загрузка объектов в режиме одноранговой связи Для загрузки будет использоваться список активных клиентов. Перед тем, как начнется фактическая загрузка, из списка выбираются случайные клиенты, и этим клиентам сразу же отправляется запрос (рис. 3.6а), чтобы узнать, находится ли у них данный объект[1]. Загрузка начнется с клиента, который быстрее всего ответит положительно (рис. 3.6b). В случае только отрицательных ответов они попытаются повторить запрос с другими клиентами. Если объект не находится ни на одном активном клиенте, вся операция загрузки объекта будет повторяться с интервалом времени снова. 26
45 3.4. ПРОТОКОЛ СВЯЗИ Разрешение конфликтов Для конфликтов, возникающих при взаимодействии клиент-сервер, пользователю будет предложено решение. Возможные решения будут следующими: Установить конфликтующую версию как текущую Поместить конфликтующую версию в соответствующее место в истории (тег CreateDate будет искусственно создан, чтобы версия правильно разместилась в истории) Сохранить обе версии (создать новая сущность для конфликтующей версии) Конфликты, возникающие в режиме одноранговой связи, будут разрешатьсяавтоматически, сохраняя обе версии. 3.4 Протокол связи В результате анализа для связи была выбрана структура WCF платформы .net Framework. Чтобы воспользоваться преимуществами, упомянутыми в анализе, коммуникационные интерфейсы будут доступны через базовую привязку http. В частности, это означает, что SOAP будет использоваться в качестве коммуникационного протокола, а файл WSDL, описывающий этот интерфейс, будет создан для текущего открытого интерфейса. Для связи также рассматривалось использование архитектуры REST, которая также хорошо поддерживается инфраструктурой WCF[42]. Но эта архитектура использоваться не будет, так как для нужд предлагаемой системы целесообразнее будет использовать протокол SOAP, лучше отвечающий требованиям к коммуникационному интерфейсу. Будут использоваться только некоторые принципы архитектурного стиля REST, такие как безгражданство или модель связи клиент-сервер. Благодаря возможности использования собственного хостинга в клиенте, который также может использовать базовую http-связку для предоставляемой службы, связь между двумя клиентами будет очень похожа на связь между клиентом и сервером. Это сходство облегчит переключение между режимами синхронизации клиент-сервер и одноранговой сети. Протокол SOAP использует формат XML для обмена сообщениями и чаще всего работает через транспортный протокол HTTP[43]. Это упрощает взаимодействие между различными платформами. Благодаря поддержке WCF этот метод связи очень прост в использовании, включая возможность отправки потока данных. Недостатком может быть инкапсуляция сообщений в формате XML, что увеличивает общий размер сообщений (например, из-за совпадения тегов, но в основном из-за кодирования потока с использованием Base64) и, соответственно, конкретный интерфейс, работающий с этим конкретным интерфейсом. генерируетсяорганизация. В примере реализации это будет поток данных файла, включая его метаданные. Для работы синхронизации фреймворк должен будет добавить к этим данным дополнительную информацию, среди которой будут идентификаторы сущности и идентификаторы ее версии (рис. 3.7). 27
46 ГЛАВА 3. ПРОЕКТ SOAP-конверта SOAP-заголовок Общая информация об объекте Метаданные файла Тело SOAP Поток данных файла Рисунок 3.7: Структура сообщения SOAP с объектом, содержащим файл По этой причине будет существовать абстрактный класс, определяющий контракт для общий интерфейс, содержащий всю необходимую информацию для фреймворка. Конкретная реализация этого контракта будет содержать данные конкретного объекта (метаданные файла и поток данных). Для этой цели больше всего подходит сериализация с использованием MessageContract[44], которая позволяет полностью контролировать SOAP-сообщение с помощью атрибутов. Благодаря этому можно отправлять поток данных в теле сообщения SOAP с помощью атрибута MessageBodyMember, а дополнительные данные затем можно сериализовать в заголовок этого сообщения SOAP с помощью атрибута MessageHeader. 3.5 Архитектура системы Для ясности описание архитектуры разделено на серверную и клиентскую стороны, которые далее подразделяются на интерфейсную и внутреннюю серверную архитектуру. Архитектура сервера показана на рис. 3.8. Сервер предоставит интерфейс StorageService для подключения клиентов. Все доступные операции сервера будут доступны через этот интерфейс. Все запросы будут передаваться на обработку фреймворку, который будет использовать доступ к базе данных через StorageRepository или доступ к конкретным сущностям через интерфейс IStorageImplementation. Реализация этого интерфейса должна быть обеспечена программистом, использующим этот фреймворк. Пример реализации с использованием платформы синхронизации файлов будет включатьбизнес-логика, в основном управляющая хранением или чтением данных. StorageRepository предоставляет доступ к базе данных для хранения метаданных, а FileAccessManager предоставляет доступ для хранения самих файловых данных. Входной класс StorageService будет пересылать отдельные запросы ответственным классам. В частности, это будут классы, выполняющие следующие функции: Сохранение и чтение сущностей. Разрешение возникших конфликтов. 28
47 3.5. АРХИТЕКТУРА СИСТЕМЫ Реализация фреймворка с использованием фреймворка Клиенты Хранилище Служба Бизнес-логика Хранилище Репозиторий Хранилище Реализация Хранилище Репозиторий FileAccess Manager Реляционная база данных Папка с сохраненными файлами Рисунок 3.8: Схема архитектуры сервера Управление пулами клиентов, включая назначение и удаление сущностей из выбранных пулов. Управление информацией о клиентских устройствах (в основном для нужд поиска клиентов для режима связи P2P) Back-end архитектура клиента Back-end архитектура клиентской части будет состоять из двух частей. Основная часть будет действовать как клиент, и ее целью будет переход в синхронное состояние путем связи с сервером или с другим клиентом. Целью второй части будет обслуживание запросов от других клиентов. Для ясности обе части архитектуры описываются отдельно. Архитектура части, используемой для обработки запросов от других клиентов, будет такой же, как и в случае с сервером (на рис. 3.8). В результате разница будет заключаться только в доступности других операций на коммуникационном интерфейсе и, следовательно, в использовании других классов, которые будут иметь несколько иную логику. Реализация с использованием фреймворка Framework Мониторинг папок Логика синхронизации Таймер Сервер Клиент Синхронизированная папка Хранилище Реализация Логика синхронизации Логика выбора клиента Сервер FileAccess Manager Хранилище Репозиторий Хранилище Репозиторий Одноранговый клиент Клиенты Реляционныебаза данных Рисунок 3.9: Диаграмма архитектуры клиента Архитектура части клиентской роли показана на рисунке 3.9. Операции синхронизации будут запускаться двумя компонентами. Один из компонентов будет в реализации с использованием фреймворка, а конкретно в данном случае это будет компонент, отслеживающий изменения содержимого папки на диске. Второй компонент, выполняющий логику синхронизации 29
48 ГЛАВА 3. ДИЗАЙН будет таймером, который будет многократно загружать новые сущности через выбранный интервал и выполнять другие необходимые операции. Как и в случае с сервером, фреймворк будет хранить данные в базе данных через Storage-Repository. Обработка конкретных сущностей будет осуществляться через интерфейсы IStorageReaderImplementation или IStorageWriterImplementation. Реализации этих интерфейсов снова должны быть предоставлены программистом, использующим эту структуру. Логика синхронизации будет отвечать за все, что так или иначе связано с синхронизацией сущностей. Основная функциональность будет следующей: Локальное обновление объектов для синхронизации с другими устройствами. Загружать новые объекты и новые версии на сервер. Эта запись будет происходить каждый раз, когда создается новый объект или версия. В случае сбоя сервера эти объекты будут загружены только при восстановлении соединения с сервером. Выявлять и разрешать конфликты. Добавляйте и удаляйте сущности из пулов клиентов. Создавайте пулы клиентов и подключайте клиентов к пулам клиентов. Логика выбора клиента для связи также будет частью фреймворка (в данном случае под клиентом подразумевается класс, обеспечивающий связь). Таким образом, целью этой части будет переключение между режимами синхронизации клиент-сервер и одноранговая сеть, поэтому она должна будет иметь возможность обнаруживать сбой соединения с сервером и его последующее восстановление. В режиме одноранговой связи эта часть также будет отвечать за выбор разных клиентов.(или одноранговые узлы) для связи. Архитектура внешнего клиента. Это описание архитектуры предназначено для клиентского приложения с примером реализации синхронизации файлов. Поскольку это приложение будет использовать графический пользовательский интерфейс, построенный с использованием среды WPF, архитектура этого приложения будет использовать архитектурный шаблон MVVM (рис. 3.10). Этот шаблон делит приложение на три части: модель, представление и модель представления. Вся реализованная логика синхронизации будет служить Моделью. Таким образом, эта часть будет содержать всю структуру синхронизации клиента (то есть всю логику для синхронизации, разрешения конфликтов, связи в обоих режимах и т. д.). При этом будет включена реализация, использующая этот фреймворк (то есть обработка файлов и отслеживание изменений в выбранной папке в файловой системе). Архитектура этой части подробно описана в подразделе Архитектура внутреннего клиента. В этом случае представление будет определено с использованием языка разметки XAML. Каждое представление будет иметь одну модель представления. Затем свойства компонентов из представления будут привязаны к выбранным свойствам в модели представления (будут связаны свойства и свойства данного компонента). ViewModel также будет посредником в доступе к модели, то есть для управления логикой синхронизации. 30
49 3.6. ОПИСАНИЕ ОСНОВНЫХ ОПЕРАЦИЙ СИНХРОНИЗАЦИИ Представление (XAML) Команда Привязка события Представление (код) Вызов метода ПредставлениеМодель Вызов метода Модель обратного вызова (логика синхронизации) Рисунок 3.10: Схема архитектуры MVVM. Источник: [45]. 3.6 Описание основных операций синхронизации В этом разделе описана последовательность шагов для выполнения основных операций синхронизации как на стороне сервера, так и на стороне клиента Создание нового объекта или версии на клиенте Рисунок 3.11: Диаграмма последовательности создания новой версии объекта на стороне клиента клиент Процедура создания нового объекта илиновая версия (показана на рис. 3.11) будет выглядеть следующим образом: 1. Создание новой записи в таблице EntityVersion и, в случае новой сущности, в таблице Entity. 31
50 ГЛАВА 3. ПРОЕКТ 2. Хранение информации о конкретном объекте (через IStorageWriterImplementation). В случае реализации примера речь пойдет только о хранении метаданных в базе данных. 3. Заполнение дополнительных данных для сущности, необходимых для отправки сущности на сервер. 4. Отправка объекта через CommunicationManager, который обеспечивает связь с сервером. 5. При успешной отправке обновления записи в EntityVersion (добавление идентификатора сервера) и, возможно, также записи в таблице Entity Создание новой сущности или версии на сервере Рисунок 3.12: Диаграмма последовательности создания новой версии сущность на сервере Процедура вставки новых сущностей или новых версий (показана на рис. 3.12) будет следующей: 1. Создание временной сущности в StagingArea. (a) Создайте запись в таблице StagingArea. (b) Хранение конкретного объекта во временном хранилище. 2. Проверка того, не конфликтует ли сущность с другой, и, если да, возвращение соответствующего ответа клиенту. 3. Если сущность успешно сохранена, в таблице EntityVersion создается запись. 4. Удаление записи из таблицы StagingArea. 5. Переместите объект в целевое хранилище (через IStorageImplementation). 32
51 3.6. ОПИСАНИЕ ОСНОВНЫХ ОПЕРАЦИЙ СИНХРОНИЗАЦИИ Получение новых сущностей на клиенте Рисунок 3.13: Схема последовательности получения новых сущностей на клиенте Процедура получения новых сущностей (показана на рисунке 3.13) будет следующей: 1. Получение списка новых сущностей через CommunicationManager обеспечение соединения с сервером или с другим выбранным клиентом. 2. Получение списка локальных сущностей. 3. Сравнение списка местных и недавно прибывших объектов, чтобы решить, какие объекты новее, а какиепоэтому они должны быть загружены. В то же время будет проверено, не конфликтуют ли сущности. 4. Создание записей в таблице EntityVersion (для входящих сущностей, которые новее локальных). 5. Загрузка отдельных сущностей через CommunicationManager, что снова обеспечивает доступное соединение. 6. Хранение конкретных сущностей с помощью IStorageWriterImplementation Получение сущности на основе запроса от клиента При обработке запроса от клиента сущность будет считываться на сервере и на клиенте одинаковым образом. Поэтому эта процедура будет описана здесь только один раз. Таким образом, процедура чтения сущностей (показана на рис. 3.14) будет следующей: 33
52 ГЛАВА 3. ДИЗАЙН Рисунок 3.14: Схема последовательности получения сущности на основе запроса от клиента 1. Поиск соответствующей записи в таблице EntityVersion. 2. Чтение определенного объекта (через IStorageReaderImplementation). 3. Заполнение дополнительных данных для считываемой сущности для нужд фреймворка. 4. Отправка объекта клиенту. 3.7 База данных Обе части системы (клиент и сервер) должны хранить данные в реляционной базе данных. Обе стороны будут работать с одним и тем же типом сущностей, поэтому схемы базы данных будут схожими. Отличие этих схем в основном будет заключаться в том, что серверная часть будет дополнительно содержать StagingArea для загрузки сущностей, а клиентская часть дополнительно будет содержать DownloadArea для еще не скачанных сущностей. Еще одно различие между схемами будет связано с разными первичными ключами на сервере и на клиентах. На стороне сервера будет использоваться Microsoft SQL Server, который будет использоваться для хранения информации обо всех сущностях и клиентах. Клиентская сторона будет использовать базу данных SQLite, в которой будут храниться только данные, необходимые для этого клиента. Обслуживание этой локальной базы данных будет особенно важно для правильного функционирования синхронизации (правильное управление версиями).сущности и разрешение конфликтов), включая работу в режиме одноранговой связи (локальное управление версиями, посредничество сущностей с другими клиентами и загрузка истории сущностей на сервер), их идентификацию по идентификатору и, возможно, GUID) и их историю версий. Значение используемых идентификаторов описано в подразделе Идентификация сущностей. Сущности будут храниться в таблице Entities, а записи истории отдельных сущностей будут в таблице 34
.
53 3.7. Версия Сущности БАЗЫ ДАННЫХ. Для упрощения запросов к базе данных таблица Entity будет содержать ссылку на последнюю (текущую) версию в таблице EntityVersion. Таблица EntityVersion снова будет содержать столбцы, используемые для идентификации (ID и, возможно, GUID). Он также будет содержать время создания, которое будет использоваться для восстановления истории версий выбранного объекта. Будет установлен флаг IsDeleted, указывающий, что сущность удалена. Последним важным столбцом в этой таблице будет вектор версий, используемый клиентами для сравнения версий друг с другом (что новее или конфликтует). Идентификатор сущности LastVersion Guid ClientPool_Entity ClientPool Entity ClientPool Id EntityVersion Id Entity CreateDate Guid VersionVector IsDeleted FolderItem Id EntityVersion ParentFolder ItemType Name Size Hash DataPath StagingArea Id VersionTo CreateDate Guid EntityGuid VersionVector IsDeleted StagingFolderItem Id StagingItem NewParentFolder DeviceName ClientPoold Имя элемента ClientPoold_ClientType Name Hash DataPath Size ClientPool_Client Операционная система ProtocolVersion ClientEndpoint Id Client IpAddress Port ConnectionType Рисунок 3.15: Схема базы данных сервера Для групп сущностей в базе данных будет таблица ClientPool. В то время каккаждый пул клиентов может содержать несколько сущностей, и в то же время каждая сущность может принадлежать нескольким пулам клиентов, эта таблица будет связана с таблицей сущностей отношением M:N. Для нужд поиска клиентов их подробная информация будет храниться в базе данных (Таблица клиентов). Каждый клиент должен быть идентифицирован уникальным способом, поэтому каждый клиент будет генерировать свой собственный GUID после первого запуска, который используется для идентификации. В дополнение к этому столбцу таблица также будет содержать дополнительную информацию, такую как имя устройства или версию протокола связи. К каждому клиенту будет подключено несколько конечных точек (таблица ClientEndpoint), которые могут либо представлять несколько текущих сетевых интерфейсов, например, WiFi и мобильный Интернет, либо могут записывать историю подключений, например, Интернет дома и на работе. 35
54 ГЛАВА 3. ПРОЕКТ Конечная точка означает IP-адрес, порт и тип подключения. Таблица Client будет связана с таблицей ClientPool отношением M:N, что позволит осуществлять поиск только тех клиентов, которые содержат необходимые сущности для синхронизации. Загрузка сущности может занять некоторое время, или после завершения загрузки может быть обнаружен конфликт сущностей. По этой причине в базе данных будет таблица StagingArea для записи временных данных, включая информацию о том, в какую версию загружается сущность. После успешной загрузки объекта в таблице EntityVersion будет создана запись, а соответствующая запись будет удалена из таблицы StagingArea. При обнаружении конфликта запись в таблице StagingArea останется до тех пор, пока этот конфликт не будет разрешен. Таблицы для конкретной реализации фреймворка Следующие две таблицы больше не для нужд фреймворка, а для конкретной реализации синхронизации файлов. Таблица FolderItem будет использоваться для хранения метаданных папок и файлов иу него будет связь 1:1 с таблицей EntityVersion. Поскольку EntityVersion представляет собой общий объект, будет проще хранить данные как для папок, так и для файлов в одной таблице и различать типы с помощью столбца значений перечисления. Кроме того, эта таблица должна содержать ссылку на родительскую папку (опять же на таблицу FolderItem), которая разрешает древовидную структуру папок, а также принадлежность файлов к конкретной папке. Файлы по-прежнему будут содержать хэш и путь к файлу, который может быть путем к диску или ключом в каком-либо хранилище BLOB-объектов. Таблица StagingFolderItem будет иметь аналогичные свойства FolderItem, с той лишь разницей, что она будет обслуживать потребности таблицы StagingArea, с которой будет иметь отношение 1:1, и при этом ссылка на родительскую папку будет указывать на Таблица FolderItem Клиентская база данных Схема базы данных на стороне клиента (рис. 3.16) будет очень похожа на схему на стороне сервера. Как уже было сказано, разница будет заключаться в добавлении или удалении некоторых таблиц. Эта разница в основном будет вызвана тем, что сервер будет ждать запроса от клиента и, следовательно, будет ожидать получения новых объектов (эти объекты будут загружены в StagingArea первыми), в то время как клиент, с другой стороны, будет должен вызывать все операции сам по себе. В связи с двухэтапной загрузкой сущностей, когда на первой фазе будет получен только список новых сущностей, необходимо будет хранить информацию о невыгруженных сущностях в таблице DownloadArea. После успешной загрузки соответствующую запись необходимо будет удалить из этой таблицы. По сравнению с серверной базой данных таблица Entity будет расширена с помощью ServerId, содержащего идентификаторы, сгенерированные сервером, вспомогательного флага, указывающего на сущности с неразрешенным конфликтом, и LastVersionNumber, содержащего последний номер локальной версии, используемый для создания новых векторов версий. Таблица EntityVersion снова будет расширена наServerId, а затем ConflictId, содержащий номер конфликта на сервере (если данная версия конфликтует). В дополнение к изменениям, упомянутым выше, также будет таблица настроек, используемая для хранения настроек или некоторой дополнительной информации, например, GUID клиента. 36
55 3.8. UI Entity Id ServerId Guid LastVersionNumber IsUnresolvedConflict LastVersion EntityVersion Id ServerId Guid VersionVector ConflictId CreateDate Entity IsDeleted DownloadArea Id ConflictOldEntityVersionId ConflictNewEntityVersionId EntityVersion ClientPool_Entity ClientPool Entity FolderItem Id ItemType Name DataPath ParentFolderEntityVersion EntityVersion Size Hash IsShared ClientEndpoint Id IpAddress Port ConnectionType LastActiveTime ClientPool Id IsConnected ClientPool_Client ClientPool Client Id ClientId DeviceName UserName OperatingSystem ProtocolVersion Setting Id Value Рисунок 3.16: Схема клиентской базы данных Таблица для конкретной реализации фреймворка Учитывая, что значения первичных ключей в этой базе данных не будут иметь никакого значимого значения, кроме связывания записей (только ServerId или GUID будет использоваться для идентификации), создание структуры файлового дерева будет более сложным. Таким образом, таблица FolderItem для родительского элемента не будет иметь ссылку на себя, а вместо этого будет иметь ссылку на родительскую EntityVersion, которая уже будет содержать действительные идентификаторы ServerId и GUID. Вторая ссылка из FolderItem на EntityVersion выполняет ту же функцию, что и на стороне сервера, т. е. связывает конкретную сущность с общим представлением сущности в отношении 1: Пользовательский интерфейс. Основная цель этой работы — создать основу для синхронизации сущности и для по этой причине будет создан только простой пользовательский интерфейс для демонстрации функциональной структуры.Приложение будет состоять из двух частей. Главное окно приложения (рисунок 3.17) будет содержать вкладки, каждая из которых будет иметь следующий вид: 37
56 ГЛАВА 3. ПРОЕКТ Синхронизация файлов Общие Конфликты общих ресурсов Журнал состояния О пути к папке синхронизации Номер порта Инициализация Основной пул клиентов C:\StoragePath 8000 Создать новый пул клиентов Подключиться к существующему пулу клиентов Запустить синхронизацию Рисунок 3.17: Дизайн пользовательского интерфейса главное окно приложения Инициализация приложения будет использоваться для настроек, необходимых для запуска синхронизации (выбор синхронизируемой папки или настройки основного пула Клиентов). Совместное использование будет использоваться для представления функций, связанных с пулами клиентов, т. е. для подключения клиента к пулу клиентов или назначения объекта пулу клиентов. Конфликты будут использоваться для перечисления всех неразрешенных конфликтов, возникших во время связи с сервером. После нажатия на конфликт открывается диалоговое окно со списком возможных решений. Состояние приложения будет отображать информацию о том, что инфраструктура в настоящее время делает для операций. В дампе журнала будут перечислены все журналы из приложения и фреймворка (в основном для целей отладки). Второй частью приложения будет значок уведомления на панели задач Windows в области уведомлений. Назначение этого значка будет заключаться в том, чтобы показать, в каком режиме синхронизации находится приложение (клиент-сервер, одноранговая сеть или синхронизация не запущена). После нажатия на этот значок отобразится список последних синхронизированных файлов. 38
57 Глава 4 Реализация В этой главе рассматриваются главным образом технические вопросы. Программное обеспечение, необходимое для разработки и эксплуатации системы, структура всего проекта (называемого Solution в Visual Studio) и метод отделения части, представляющей структуру синхронизации, от части, содержащей реализацию доступа к определенному типу сущности описаны здесь. 4.1 Программное обеспечение дляразработка В связи с выбором платформы .net Framework 4.5 и языка программирования C#, был выбран дополнительный софт. Так как разработка и серверной части, и клиентской части происходила на одном компьютере, также необходимо было установить программное обеспечение для работы серверной части. В первую очередь необходимо было выбрать среду разработки, а именно Microsoft Visual Studio Enterprise, которая также включает в себя удаленный отладчик, который был полезен в случае возникновения ошибки на устройстве без установленной Visual Studio. В качестве операционной системы для разработки была выбрана Microsoft Windows 10 Pro x64. В качестве системы базы данных для серверной части системы была выбрана Microsoft SQL Server 2014 Developer Edition. Все упомянутые выше программы доступны учащимся программы DreamSpark Premium. Для развертывания и тестирования серверной части из-за используемого программного обеспечения и использования фреймворка WCF необходимо было использовать веб-сервер IIS версии 10. Этот сервер без проблем устанавливается в выбранной редакции Windows . 4.2 Программное обеспечение для работы с системой Как клиентская, так и серверная часть могут работать в операционной системе Microsoft Windows с установленной средой .net Framework 4.5. Для серверной части системы по-прежнему требуется установленный веб-сервер IIS не ниже версии 7. Поэтому минимальные поддерживаемые версии Windows следующие: Microsoft Windows Vista SP2 Microsoft Windows Server 2008 SP2 39
58 ГЛАВА 4. РЕАЛИЗАЦИЯ 4.3 Структура проекта Вся система разделена на три части. Это реализация сервера, реализация клиента и общая часть. Как на стороне сервера, так и на стороне клиента используются библиотеки, описанные в подразделе 2.7 Технические решения. Общие проекты платформы: InterClientCommunication.DataContracts содержит типы данных, используемые в открытом интерфейсе связи.InterClientCommunication.Shared содержит независимые общие классы (например, для векторов версий). InterClientCommunication.UnitTest используется для тестирования независимых классов (например, из проекта Shared). Общий проект синхронизации файлов: InterClientCommunication.FileSync.DataContracts содержит типы данных, используемые в открытом интерфейсе связи для нужд синхронизации файлов. Сервер состоит из каркасной части и части синхронизации файлов (рис. 4.1). Сервер состоит из следующих проектов: InterClientCommunication.Server используется только для отображения коммуникационного интерфейса и настройки сервера. Затем управление передается проекту Server.Core. InterClientCommunication.Server.Core содержит всю логику синхронизации фреймворка. InterClientCommunication.Server.DataEntities обеспечивает доступ к базе данных. InterClientCommunication.Server.FileSync содержит функциональные возможности для обработки определенных сущностей (чтение и сохранение файлов). Функции вызываются из проекта Server.Core. Клиент снова состоит из части фреймворка и части синхронизации файлов (рис. 4.2). Клиент состоит из следующих проектов: InterClientCommunication.Client содержит пользовательский интерфейс приложения, запускает структуру синхронизации и в то же время предоставляет доступ к определенным объектам (чтение и сохранение файлов). InterClientCommunication.Core содержит логику синхронизации платформы, включая обнаружение клиентов и переключение между режимами синхронизации клиент-сервер и одноранговой сети. В то же время этот проект включает поддержку предоставления интерфейса связи для однорангового режима. InterClientCommunication.DataEntities обеспечивает доступ к базе данных. 40
59 4.4. ОТДЕЛЕНИЕ СТРУКТУРЫ ОТ СИНХРОНИЗАЦИИ КОНКРЕТНЫХ СУЩЕСТВ Рисунок 4.1: Схема компонентовсерверная часть Рисунок 4.2: Схема компонентов клиентской части 4.4 Отделение фреймворка от синхронизации конкретных сущностей Фреймворк устроен таким образом, что содержит несколько определенных интерфейсов. Использование фреймворка заключается в создании классов, реализующих эти интерфейсы, и их последующей регистрации в IoC Container. Эти классы (компоненты) должны быть зарегистрированы в Conatiner как сервисы под соответствующим интерфейсом. Затем эти классы создаются контейнером IoC, а структура синхронизации просто вызывает соответствующие методы по мере необходимости. 41
60 ГЛАВА 4. РЕАЛИЗАЦИЯ Серверная часть Как уже упоминалось, серверная часть содержит проект ICC.Server, который используется только для предоставления коммуникационного интерфейса. Платформа не может позаботиться об открытии этой службы напрямую, потому что для раскрытия требуется знание конкретного типа объекта, передаваемого во время связи. Когда этот тип известен, можно создать коммуникационный интерфейс, заданный универсальным интерфейсом IStorageService и реализованный универсальным классом StorageService в проекте ICC.Server.Core. Это означает, что StorageService предоставляет все серверные функции платформы. Методы конкретной реализации вызываются только при работе с вещами, связанными с конкретными сущностями (сохранение и чтение файлов). Этот вызов происходит через интерфейс IStorageImplementation. Поэтому для правильной работы синхронизации необходимо зарегистрировать класс, реализующий этот интерфейс, на стороне клиента контейнера IoC на стороне клиента. Доступ к функциям платформы на стороне клиента осуществляется через класс Main-FrameworkController в проекте ICC.Core. . Конфигурация, инициализация и синхронизация новых сущностей или версий могут выполняться в этом классе. Вызов методов для работы с вещами, связанными с конкретными сущностями (файлами), осуществляется черезинтерфейс IStorageReaderImplementation (для чтения сущностей) и интерфейс IStorageWriterImplementation (для записи сущностей). Для корректной работы синхронизации необходимо зарегистрировать классы, реализующие эти интерфейсы, в IoC Container клиента. Вызов методов через эти интерфейсы осуществляется как для выполнения локальных операций синхронизации (например, сохранения вновь загруженного объекта), так и при обработке запроса от другого клиента в режиме одноранговой связи Другие определенные интерфейсы В дополнение к уже упомянутым интерфейсам, платформа требует реализации и регистрации интерфейса IDatabaseSetup (как на стороне сервера, так и на стороне клиента), используемого для настройки NHibernate для обеспечения доступа к базе данных. Этот интерфейс также позволяет вам устанавливать сопоставления NHibernate для некоторых других объектов базы данных и, таким образом, позволяет конкретной реализации синхронизации использовать ту же базу данных, что и инфраструктура. Преимущество в том, что вы можете использовать уже настроенный NHibernate для хранения собственных данных в базе данных. 42
61 Глава 5 Тестирование В связи с характером программы (среда синхронизации) было решено провести основное тестирование с использованием образца (реализации) структуры синхронизации файлов. Эта синхронизация подходит для тестирования, так как это достаточно сложная синхронизация, где нужно учитывать требовательность к передаче данных, когда сущностей может быть большое количество и при этом их размер может варьироваться от единиц килобайт до сотен мегабайты. Кроме того, здесь очень легко может возникнуть множество различных конфликтов. Так как фреймворк создавался одновременно с реализацией файловой синхронизации, то также необходимо было протестировать развертывание фреймворка для синхронизации сущностей какого-то другого типа. По этой причине также была реализована упрощенная синхронизация телефонных контактов.Цель этого теста состояла в том, чтобы выяснить, ведет ли себя система как фреймворк, и, следовательно, легко ли ее взять и развернуть для синхронизации каких-то совершенно разных сущностей. 5.1 Тестирование через файловую синхронизацию Как уже упоминалось, фреймворк создавался одновременно с его реализацией через файловую синхронизацию. Именно поэтому была создана тестовая версия десктоп-клиента, которая позволяла вручную управлять отдельными шагами фреймворка синхронизации. В полученной версии клиента этот элемент управления удален, и фреймворк автоматически позаботится о синхронизации. В полученном клиенте не реализована полная синхронизация файлов, потому что для тестирования фреймворка было достаточно упростить эту реализацию (например, синхронизировать файлы только с одного уровня папки и, таким образом, игнорировать все вложенные папки). Тестовая среда Для тестирования необходимо было создать тестовую среду. Окружающая среда. Из-за особенностей системы, в которой происходит синхронизация между сервером и несколькими клиентами, для тестирования необходимо было задействовать несколько устройств. Конкретно нужно было протестировать синхронизацию в двух режимах: Клиент-сервер Одноранговый 43
62 ГЛАВА 5. ТЕСТИРОВАНИЕ Для самого базового тестирования связи в режиме клиент-сервер было достаточно одного устройства с развернутым сервером и работающим клиентом. Для тестирования синхронизации уже требовалось добавить как минимум еще одно устройство для проверки распространения изменений от одного клиента к другому. Для тестирования одноранговой синхронизации также требовалось как минимум два устройства, на которых запущено клиентское приложение. Для проверки полной функциональности фреймворка, включая автоматическое переключение между обоими режимами связи, требовался как минимум следующий список устройств: 1x сервер 2x клиент Клиент 1 Клиент 2 Сервер Клиент 1 Клиент 2 Сервер Клиент 3 Клиент 4 (a ) Тестированиесинхронизация клиент-сервер Клиент 3 Клиент 4 (b) Тестирование одноранговой синхронизации Рис. 5.1. Конфигурация подключения устройства для тестирования Клиент 1 Клиент 2 Сервер Клиент 3 Клиент 4 Рис. Все эти устройства необходимо было подключить к общей тестовой сети, где устройства могут видеть друг друга и, таким образом, общаться друг с другом (рис. 5.1а). В этой сети также необходимо было обеспечить возможность отключения сервера (рис. 5.1б), что позволило протестировать автоматическое переключение между режимами связи клиент-сервер и одноранговый в случае отказа сервера. 44
63 5.1. ТЕСТИРОВАНИЕ ЧЕРЕЗ ФАЙЛОВУЮ СИНХРОНИЗАЦИЯ При создании тестовой сети также тестировался вариант на рис. 5.2, где Клиент 4 не подключен к сети, но подключен к Клиенту 3, с которым образует вторую сеть, не связанную с основной сеть. Благодаря такой конфигурации устройства Клиент 1, Клиент 2 и Клиент 3 работают в режиме связи клиент-сервер, а Клиент 4 — в режиме одноранговой сети. Поэтому само тестирование проводилось на устройствах с параметрами, указанными в таблице 5.1. Таблица 5.1: Список тестового оборудования Устройство Процессор Память Операционная система Рабочий стол Intel Core i ГГц 16 ГБ Windows 10 Pro x64 Ноутбук Intel Core i5-3427u 1,8 ГГц 4 ГБ Windows 8.1 x64 Виртуальная машина 1 ядро 2 ГБ Windows 7 Professional x Тестовое оборудование Pro мониторинг активности приложения и состояния базы данных потребовались средства, перечисленные в табл. 5.2. Таблица 5.2: Список инструментов тестирования Инструмент log4net Браузер БД для SQLite Microsoft SQL Server 2014 Management Studio Oracle VM VirtualBox Тестовый клиент WCF Описание Ведение журналаинструмент для перечисления всех важных событий из программы. Инструмент для создания, просмотра и редактирования файлов базы данных SQLite. Инструмент администрирования Microsoft SQL Server, который также включает инструменты для просмотра и редактирования таблиц базы данных. Инструмент для виртуализации (управление виртуальными машинами). Инструмент для тестирования сервисов WCF (создание и отправка запросов к заданному сервису) Сценарии тестирования и результаты тестирования При подготовке тестовой среды необходимо было выполнить ряд тестовых действий, чтобы убедиться, что система работает надежно и не проявляет непредвиденных поведение. Для этого был создан документ со списком отдельных шагов, который можно найти в Приложении D, Список шагов для тестирования. 45
64 ГЛАВА 5. ТЕСТИРОВАНИЕ В ходе разработки этой процедурой было обнаружено много ошибок, которые впоследствии были исправлены. Во время окончательного тестирования с использованием этого списка проблем обнаружено не было. Недостатком этого тестирования, однако, было то, что оно выполнялось только одним человеком и, следовательно, система не подвергалась слишком большой нагрузке, в связи с чем некоторые ошибки, связанные с параллельным выполнением действий в системе, могли быть не обнаружены. 5.2 Тестирование поиска клиента Тестирование поиска клиента довольно сложно, потому что платформа запускает все три метода поиска полностью автоматически. По этой причине необходимо было создать такую тестовую среду, которая позволяла бы тестировать отдельные механизмы по отдельности. Следовательно, эта среда должна была иметь возможность исключать отдельные механизмы поиска. Сервер Сеть 1 Сеть NAT 2 Маршрутизатор Сеть 3 Сеть 4 Рисунок 5.3: Конфигурация сетевого подключения устройства для тестирования поиска клиентов Тестовая среда была основана на схеме на Рисунке 5.3, где всегда было достаточно использовать только некоторые части для тестирования отдельных механизмов поиска клиентов . Таким образомпостроенная сеть разрешала связь между всеми доступными устройствами, за исключением случаев, когда любой клиент из сетей 1, 3 и 4 пытался установить соединение с устройством в сети 2, которое было заблокировано включенным NAT. Вывод из эксплуатации отдельных механизмов поиска: поиск на сервере был выведен из эксплуатации простым отключением сервера от остальной сети. Многоадресный поиск был устранен за счет использования маршрутизатора с включенным NAT. Поиски с использованием локальной базы данных были отклонены путем признания недействительными соответствующих записей в базе данных. Эта недействительность произошла путем изменения IP-адресов клиентских устройств, подключенных к сети. 46
65 5.3. ТЕСТИРОВАНИЕ ОБРАЗЦА ПРИЛОЖЕНИЯ С ПОЛЬЗОВАТЕЛЯМИ Тестирование поиска клиентов с использованием многоадресной рассылки Требуется: Используйте сеть 3. Откажитесь от поиска на сервере и в локальной базе данных. Тестирование обнаружения клиента с использованием требуемого сервера: Используйте сеть 1, сеть 2 и сеть 3. Откажитесь от многоадресной рассылки и обнаружения локальной базы данных. Требуется тестирование обнаружения клиента с использованием локальной базы данных: Используйте сеть 2 и сеть 3. Отключите обнаружение сервера и многоадресную рассылку. Сохраните клиентов, найденных с помощью двух предыдущих методов, в локальной базе данных. Результат теста Ключевым наблюдением этого теста было то, что комбинация этих методов может найти множество устройств, включая те, с которыми невозможно установить связь. С другой стороны, благодаря полному списку найденных устройств также можно установить связь с устройствами, расположенными за разными маршрутизаторами (рис. 5.3, связь между сетью 3 и сетью 4), и, таким образом, можно, например, через Интернет. 5.3 Тестирование примера приложения с пользователями Учитывая, что для тестирования системы под нагрузкой одного человека недостаточно, было также проведено неформальное тестирование с несколькими пользователями. Цель этого теста состояла в том, чтобы обнаружить проблемы, связанные с параллельным выполнением действий, и это былонеобходимо, чтобы все участники одновременно приняли участие в этом тесте. Целью этого теста не было найти ошибки, связанные с пользовательским интерфейсом. Тестовая среда для этого теста была описана в подразделе «Тестовая среда». Хотя цель теста заключалась в основном в обнаружении проблем с инфраструктурой, участники в основном обнаружили проблемы в реализации синхронизации файла примера. Некоторые проблемы были связаны с функциональностью, но многие были связаны с пользовательским интерфейсом. Тестирование проходило в несколько итераций, между которыми проводилось исправление обнаруженных ошибок.Результат первой итерации.Первая итерация все еще проводилась на разрабатываемой системе, которая по-прежнему использовала только отладочный пользовательский интерфейс, предназначенный для разработки. Благодаря этому участники в основном сосредоточились на тестировании функциональности. В ходе этого теста было обнаружено множество проблем, в основном связанных с переходом в режим одноранговой связи, который перестал работать. Из-за этой проблемы было принято решение прекратить тестирование в этой итерации и сосредоточиться на доработке системы, включая создание нового пользовательского интерфейса. 47
66 ГЛАВА 5. ТЕСТИРОВАНИЕ Результат второй итерации В этой итерации уже была создана первая версия пользовательского интерфейса и фреймворк прошел тест, описанный в подразделе Тестовые сценарии и результаты тестирования. Во время этого теста было обнаружено много серьезных проблем. Две наиболее важные проблемы были связаны с реализацией примера синхронизации файлов. В частности, это была невозможность удалить файл и сбой приложения при попытке синхронизации файла размером более 1,5 ГБ (из-за несоблюдения максимального размера). Конфигурация одноранговой связи, настроенная на однопоточную обработку запросов, также была проблемой. Таким образом, клиент всегда обслуживал не более одного запроса идругие клиенты не смогли установить с ним связь в то время. Это вызвало значительное замедление синхронизации. Но многие открытия были связаны с пользовательским интерфейсом примера приложения. Но целью этого интерфейса была в основном демонстрация функциональности фреймворка, поэтому он не предназначался для тестирования. Тем не менее, некоторые из этих идей были впоследствии учтены.Результат третьей итерации Перед этой итерацией тестирования была добавлена поддержка удаления и переименования файлов. Кроме того, была добавлена возможность простого обмена файлами для демонстрации работы механизма клиентских пулов. В фреймворке повышена стабильность (в основном устойчивость к ошибкам пользовательской реализации синхронизации и к сбоям при передаче данных). Пользовательский интерфейс примера приложения был улучшен для упрощения инициализации программы, а элементы управления стали более понятными. Для лучшего отображения текущего состояния на панель задач Windows добавлен значок уведомления. Результатом тестирования этой итерации стало повышение удовлетворенности участников пользовательским интерфейсом и функциональностью синхронизации. Тем не менее, было обнаружено несколько мелких ошибок (например, неправильное обновление некоторых информационных элементов). Поскольку это были лишь незначительные ошибки, они были исправлены без дальнейших итераций пользовательского тестирования. 5.4 Тест развертывания фреймворка Были созданы подробные инструкции по развертыванию фреймворка для синхронизации произвольных сущностей, которые можно найти в Приложении B Инструкции по использованию фреймворка. В рамках этого теста мы следовали этому руководству, и цель состояла в том, чтобы выяснить, является ли это руководство полным и можно ли также использовать платформу для синхронизации сущностей, отличных от файлов. Результат теста. При развертывании платформы для синхронизации новых сущностей серьезных проблем не возникло. был обнаружен. Ошибки были обнаружены только в самой инструкции, где некоторые отсутствовалишаги, которые были немедленно завершены. 48
67 Глава 6 Заключение В ходе решения данной работы была спроектирована и реализована система с клиент-серверной архитектурой, обеспечивающая синхронизацию общих объектов данных. Все объекты, синхронизированные этой системой, имеют версии, и таким образом создается их история. Архитектура этой системы предназначена для отделения общей логики синхронизации от обработки объектов определенного типа, таких как файлы. Другими словами, фреймворк берет на себя всю синхронизацию, включая обеспечение связи, а использование этого фреймворка заключается в реализации доступа к определенному типу сущностей, включая создание пользовательского интерфейса клиентского приложения. Фреймворк на клиентской части системы может обнаружить потерю и восстановление соединения с сервером и, исходя из текущего состояния, позаботиться о переключении связи между режимами клиент-сервер и одноранговый. Реализация, использующая этот фреймворк, вообще не должна беспокоиться о текущем способе связи, потому что фреймворк автоматически позаботится обо всех необходимых шагах. С точки зрения использования фреймворка нет никакой разницы между двумя способами коммуникации. Изменение состояния клиентов во время P2P-связи фиксируется несколькими механизмами. Постоянно ведется поиск новых клиентов. Найденные клиенты проверяются на доступность перед началом связи. Если текущая связь с другим клиентом прерывается, данная операция повторяется с другим клиентом. Для демонстрации функциональности были созданы сервер и клиент, синхронизирующие файлы с помощью этого фреймворка. Но основной целью этой работы было создание фреймворка для синхронизации, поэтому функционал этого примера клиента был упрощен. Полученная функциональность системы, таким образом, отвечает всем поставленным целям и требованиям. 6.1 Сложность переключения между режимами связи В ходе работы было установлено, чтопроектирование и создание системы, позволяющей осуществлять плавный переход между режимами клиент-серверной и одноранговой синхронизации, — дело непростое, и вокруг этого нужно решить множество проблем. В случае связи только в режиме клиент-сервер или только в режиме peer-to-peer механизмы синхронизации однозначны и по ним работает вся система. Однако в случае совмещения обоих способов связи необходимо использовать оба этих механизма, 49
68 ГЛАВА 6. ЗАКЛЮЧЕНИЕ каждый из которых может функционировать по-разному. Примером может служить иной способ разрешения конфликтов, или решения, какая версия сущности является текущей (в случае общения в клиент-серверном режиме сервер всегда прав, а в случае однорангового режима каждый клиент должен решить сам, используя векторы управления версиями). Помимо решения проблем, связанных с различием этих механизмов синхронизации, необходимо также решить проблемы, связанные с переходами между двумя режимами связи. Примером может служить переход из режима одноранговой связи в режим клиент-сервер, когда необходимо выгрузить на сервер все данные, которые были созданы при одноранговой синхронизации. Все клиенты должны попытаться выполнить эту загрузку, так как у каждого может быть свой набор данных. Это может вызвать множество конфликтов на сервере, которые нужно как-то разрешить (например, вмешательством пользователя). Вероятно, по указанным выше причинам все существующие решения синхронизации, описанные в данной работе, работают только в одном выбранном режиме связи. 6.2 Возможности для улучшения системы в будущем В ходе анализа, а также во время проектирования и внедрения появилось много возможностей для улучшения этой системы. Все эти усовершенствования выходят за рамки данной работы. Безопасность системы Вся система может быть дополнена различными формами безопасности.В частности, можно ввести управление пользователями и соответствующую аутентификацию и авторизацию. Шифрование связи также будет связано с этим. Реализация аутентификации и авторизации в режиме связи клиент-сервер была бы довольно простой. Хуже ситуация может возникнуть в режиме одноранговой связи, когда аутентификация и авторизация также должны быть решены между отдельными клиентами Оптимизация связи Передача данных может быть оптимизирована несколькими способами. Важным элементом оптимизации будет, особенно в случае больших объектов, разделение передачи объекта на несколько частей (это будет важно, например, в случае больших файлов, которые будут передаваться блоками, т.е. размером 4 МБ). Это может ускорить передачу в режиме одноранговой связи, когда отдельные части сущностей могут быть загружены с разных клиентов. Существенной оптимизацией мог бы стать механизм, который в режиме связи клиент-сервер сначала пытался бы загрузить сущности от других клиентов, и только в случае неудачи загружать данные сущности напрямую с сервера. Это может снизить нагрузку на сервер и увеличить скорость передачи данных между клиентами в локальной сети. Другой механизм оптимизации будет обнаруживать, если объект с теми же данными еще не был загружен на сервер в прошлом, так как это может устранить необходимость отправки всего объекта. То же самое может быть верно и для противоположного направления, т.е. если бы сущность с теми же данными уже была на клиенте, ее не нужно было бы скачивать. 50
69 6.2. ВОЗМОЖНОСТИ ДЛЯ БУДУЩЕГО СОВЕРШЕНСТВОВАНИЯ СИСТЕМЫ Для ускорения передачи было бы хорошо распараллелить операции загрузки и выгрузки сущностей. Для этого нужно было бы создать какую-то очередь для этих операций, так как количество выполняемых операций пришлось бы как-то ограничивать. В режиме одноранговой связи хорошо бы внедрить более умныемеханизм выбора разных клиентов для связи. Некоторым клиентам можно отдать предпочтение на основании различных метрик, таких как способ и качество сетевого соединения Связь между клиентами В режиме одноранговой связи было бы хорошо решить способ обмена данными даже с устройствами, расположенными за маршрутизатором с включенным НАТ. В этом случае, вероятно, необходимо было бы создать какой-то канал с возможностью дуплексной связи. Клиенты в режиме одноранговой связи могли начать использовать другой способ поиска клиентов, а именно знание других клиентов, с которыми установлено соединение. В некоторых случаях это может увеличить количество найденных клиентов.Векторы версионностиВ данной работе векторы версионности используются в их базовом виде, потому что они выполняют все, что от них требовалось в ТЗ функционала. Однако недостатком этих векторов является их увеличивающийся размер с увеличением числа клиентов, участвующих в синхронизации. Для того, чтобы сделать работу с этими векторами более эффективной и сэкономить память, было бы хорошо ввести какой-то механизм, который бы уменьшал размер этих векторов Дальнейшие улучшения фреймворка Другие способы улучшения фреймворка включают расширение функционала для управления версиями историю либо на сервере, либо на стороне клиента. Еще одним важным функционалом будет введение механизма очистки локальной базы данных от старых или устаревших записей Расширение функционала примера синхронизации файлов Функциональность примера использования фреймворка для синхронизации файлов может быть расширена за счет следующие пункты: Синхронизируйте файлы, находящиеся во вложенных папках. Улучшить механизм детектирования изменений файлов (корректно детектировать все операции и отфильтровывать множественные детектирования одного и того же события, инициированного системным компонентом дляотслеживание изменений в файловой системе). Работа с файловыми блокировками (любая другая программа может в любой момент заблокировать доступ к файлу и поэтому этот файл не может быть синхронизирован). 51
70 ГЛАВА 6. ЗАКЛЮЧЕНИЕ Повторно проанализируйте синхронизированную папку на диске после запуска приложения (если во время работы приложения не произошло никаких изменений). Постоянно расширяйте функциональность приложения всеми новыми функциями, поддерживаемыми фреймворком. 52
71 Литература [1] DEE, Matt. Синхронизация внутри локальной сети [онлайн]. Технический блог Dropbox, [цит.]. Доступна с: . [6] Примечания к выпуску 2012 года [онлайн]. SpiderOak, [цит.]. Доступна с: . [7] Что насчет DirectSync? Синхронизация без облака! [онлайн]. Справочный центр Cubby, [цит.]. Доступна с: . [8] Обнаружение WCF [онлайн]. Сеть разработчиков Майкрософт, [цит.]. Доступна с: . [10] Глава 4: Распределенные и параллельные вычисления [онлайн]. Калифорнийский университет, Беркли, [цит.]. Доступна с: . [11] КУРКОВСКИЙ, Стан. Архитектуры распределенных систем [онлайн]. Департамент компьютерных наук Центрального государственного университета Коннектикута, [цит. Доступно по: 72 ССЫЛКИ [12] Авторы Википедии. Запросить ответ [онлайн]. Википедия, Бесплатная энциклопедия, [цит. Доступна с: . [13] Авторы Википедии. Опубликовать шаблон подписки [онлайн]. Википедия, Бесплатная энциклопедия, [цит. Доступна с: . [14] Услуги хостинга [онлайн]. Сеть разработчиков Майкрософт, [цит.]. Доступна с: . [16] Ким, Юнсу и Хун Чой. Синхронизация данных и разрешение конфликтов для мобильных устройств [онлайн]. Отделение Компьютерной инженерии, Национальный университет Чунгнам, [цит. ]. Доступна с: . [17] Маккормак, Дрю. Синхронизация данных [онлайн]. objc.io, [цит.]. Доступна с: . [18] ПАРКЕР, Дуглас и др. Обнаружение взаимной несогласованности в распределенных системах. Сделки с программным обеспечениемИнженерное дело [19] Авторы Википедии. Вектор версии [онлайн]. Википедия, Бесплатная энциклопедия, [цит. Доступне з: . [20] БАКЕРО, Карлос. Векторы версии не являются векторными часами [онлайн]. HASlab, [цит.]. Доступне з: . [21] PREGUICA, Nuno, et al. Векторы пунктирной версии: эффективное отслеживание причинно-следственных связей для распределенных хранилищ ключей и значений [онлайн]. Департамент информатики Университета Минью, [цит. ]. Доступне з: . [22] Обзор .net Framework [онлайн]. Сеть разработчиков Майкрософт, [цит.]. Доступне з: . [23] Шаблон для создания универсальных служб WCF [онлайн]. CodeProject, [цит.]. Доступне з: . [24] ЗЕЛЕНЫЙ, Роберт. Введение в Windows Communication Foundation [онлайн]. Сеть разработчиков Майкрософт, [цит.]. Доступне з: . 54
73 ЛИТЕРАТУРА [25] НАГЕЛЬ, Кристиан, Джей ГЛИНН и Морган СКИННЕР. Профессиональный C# 5.0 и .net Wrox, ISBN [26] ТРОЭЛЬСЕН, Эндрю. Pro C# 5.0 и .net 4.5 Framework. Apress, ISBN [27] Введение в WPF [онлайн]. Сеть разработчиков Майкрософт, [цит.]. Доступне з: . [29] Авторы Википедии. Внедрение зависимостей [онлайн]. Википедия, Бесплатная энциклопедия, [цит. Доступне з: . [30] Документация Castle Windsor [онлайн]. Проект замка, [цит.]. Доступне з: . [31] Лицензия Apache версии 2.0 [онлайн]. Apache Software Foundation, [цит.]. Доступне з: . [34] Документация NHibernate [онлайн]. NHibernate, [цит.]. Доступне з: . [36] Возможности Apache log4net [онлайн]. Apache Software Foundation, [цит.]. Доступно из: 74 ЛИТЕРАТУРА [40] Синхронизация данных [онлайн]. Вики TrailDevilsSync, [цит.]. Доступне з: . [41] Авторы Википедии. Глобальный уникальный идентификатор [онлайн]. Википедия, Бесплатная энциклопедия, [цит. Доступне з: . [42] ФЛАНДЕРС, Джон. RESTfull.NET. O Reilly Media, ISBN [43] СКОННАРД, Аарон. Понимание SOAP [онлайн]. МайкрософтСеть разработчиков, [цит.]. Доступна с: . [44] Использование контрактов сообщений [онлайн]. Сеть разработчиков Майкрософт, [цит.]. Доступна с: . 56
75 Приложение A Список используемых сокращений GUID Глобальный уникальный идентификатор HTTP Протокол передачи гипертекста IIS Internet Information Services IoC Инверсия управления IP Интернет-протокол LAN Локальная сеть MVVM Model-View-ViewModel NAT Преобразование сетевых адресов ORM Объектно-реляционное сопоставление P2P Peer — одноранговый REST Передача репрезентативного состояния SOAP Простой протокол доступа к объектам SQL Язык структурированных запросов UDP Протокол пользовательских дейтаграмм URL Унифицированный указатель ресурсов WCF Windows Communication Foundation WPF Windows Presentation Foundation WSDL Язык описания веб-служб XAML Расширяемый язык разметки приложений XML Расширяемый язык разметки 57
76 ПРИЛОЖЕНИЕ A. СПИСОК ИСПОЛЬЗУЕМЫХ СОКРАЩЕНИЙ 58
77 Приложение B. Руководство по использованию платформы Как серверная, так и клиентская части используют Castle Windsor, поэтому обе части имеют доступный для использования контейнер IoC. Для правильного функционирования фреймворка некоторые компоненты даже требуется зарегистрировать в этом Контейнере. Framework имеет библиотеки NHibernate для доступа к базе данных и AutoMapper для сопоставления сущностей, зарегистрированных в контейнере. Обе эти библиотеки полностью доступны для использования вне фреймворка. B.1 Ввод сервера в эксплуатацию 1. Создайте новую базу данных на сервере базы данных. 2. Папка базы данных содержит SQL-скрипты для создания базы данных. Запустите все эти сценарии один за другим в соответствии с их числовым обозначением. 3. В Visual Studio создайте новый проект, который будет содержать контракты данных (классы, представляющие данные, отправляемые по сети). Добавьте ссылку на System.ServiceModel в этот проект. В этом проекте создайте класс, который наследуется отInterClientCommunication.DataContracts.Shared.EntityContractBase (этот класс будет представлять переданные сущности для синхронизации). Добавьте атрибут MessageContract в этот вновь созданный класс и для каждого сериализуемого свойства добавьте атрибут MessageHeader для размещения в заголовке сообщения или атрибут MessageBodyMember для размещения в тексте сообщения. 4. Создайте новый проект приложения-службы WCF в Visual Studio (этот проект будет использоваться для предоставления интерфейса связи). В этом проекте добавьте ссылку на InterClientCommunication.Server.Core и на проект, содержащий контракты данных (созданные в предыдущем пункте). Скопируйте файлы конфигурации Web.config и Server.Container.config в этот проект. 59
78 ПРИЛОЖЕНИЕ B. ИНСТРУКЦИИ ПО ИСПОЛЬЗОВАНИЮ ФРЕЙМЕВОРКА В файле конфигурации Web.config следующая или аналогичная строка может быть найдена в трех местах: InterClientCommunication.Server.Core.StorageService 1[[InterClientComm unication.filesync.datacontracts. folderitementitycontract,interclientcommunication .filesync.datacontracts,version= ,culture=neutral,publickeytoken=null]] Важно переопределить то, что находится внутри двойных квадратных скобок, на путь контракта данных, который наследуется от EntityContractBase. Внимание, на первом месте полный путь к данному классу и на втором месте путь к сборке. Файл конфигурации Server.Container.config используется для настройки контейнера Castle Windsor, поэтому на данный момент его можно оставить без изменений. 5. В Visual Studio создайте новый проект, содержащий классы для хранения и чтения синхронизированных сущностей и настройки базы данных. В этом проекте добавьте ссылку на InterClientCommunication.Server.Core, InterClientCommunication.Server.DataContracts, InterClientCommunication.Shared в проект, содержащий новые данныеконтракты и в библиотеку NHibernate. Добавьте ссылку на этот проект в предыдущий проект (открывая коммуникационный интерфейс). Создайте новый класс, который будет реализовывать интерфейс InterClientCommunication.Server.Core.Installer.IDatabaseSetup (этот класс будет использоваться для настройки доступа к БД и добавления новых сборок с сущностями, с которыми должен работать NHibernate). Создайте новый класс, который будет реализовывать интерфейс InterClientCommunication.Server.Core.Manager.IStorageImplementation (этот класс будет обрабатывать сущности чтения и записи сущностей в некоторое хранилище). В качестве универсального типа используйте уже созданный контракт (наследующий от EntityContract-Base). Эти два новых класса необходимо зарегистрировать как службу данного интерфейса в Контейнере (это можно сделать в конфигурационном файле Server.Container.config). 6. Реализуйте методы, определенные всеми используемыми интерфейсами. 7. Сервер будет работать через проект, созданный как приложение-служба WCF. В свойствах проекта на вкладке Web желательно установить развертывание сервера на Local IIS. По умолчанию результирующая служба будет работать по следующему адресу: B.2 Ввод клиента в эксплуатацию Клиент использует базу данных SQLite, созданную им самим, поэтому нет необходимости настраивать строку подключения и т. д., а также нет необходимости запускать SQL скрипты для создания таблиц. 60
79 Б.2. РЕАЛИЗАЦИЯ КЛИЕНТА Доступ к функциям платформы осуществляется через класс InterClientCommunication.Core.MainFrameworkController. Клиент должен быть запущен с правами администратора (чтобы открыть коммуникационный интерфейс для однорангового режима). 1. В Visual Studio из предыдущих шагов уже должен быть проект, содержащий контракты данных с классом, наследуемым от EntityContractBase (он был создан при создании сервера). 2. Создайте новый проект в Visual Studio,который будет представлять результирующий клиент (например, приложение WPF). В этом проекте добавьте ссылку на InterClientCommunication.Core и на проект, содержащий контракты данных (упомянутые в предыдущем пункте). Добавьте пакет System.Data.SQLite.Core с помощью диспетчера пакетов NuGet. Скопируйте в этот проект конфигурационный файл App.config (важно то, что находится внутри тега). В конфигурационном файле App.config эту или подобную строку можно найти всего в четырех местах: InterClientCommunication.DataContracts.IPeerService 1[[InterClientCommunication.filesync.datacontracts.folderitementitycontract,interclientc ommunication.filesync.datacontracts,version= ,culture =neutral,p ublickeytoken=null]] Важно переопределить то, что находится внутри двойных квадратных скобок, на путь к контракту данных, который наследуется от EntityContractBase. Внимание, на первом месте полный путь к данному классу и на втором месте путь к сборке. Вам также необходимо установить URL-адрес сервера в App.config. Конкретно это настройка атрибута адреса в теге, который находится внутри тега. Затем добавьте в проект app.manifest (этот шаг не является абсолютно необходимым). Измените атрибут уровня внутри тега на requireadministrator для запуска приложения с правами администратора. 3. В этом проекте или в новом необходимо будет создать классы, реализующие конфигурацию базы данных, конфигурацию Castle Windsor Container, а также хранение и чтение сущностей. В этот выбранный проект добавьте ссылку на InterClientCommunication.Core, InterClientCommunication.DataContracts, InterClientCommunication.Shared, проект, содержащий контракты данных, а также библиотеки NHibernate и Castle Windsor. Создайте новый класс, который будет реализовывать интерфейсInterClientCommunication.Core.Installer.IContainerInstaller (этот класс будет посредником при настройке контейнера Castle Windsor). Создайте новый класс, который будет реализовывать интерфейс InterClientCommunication.Core.Installer.IDatabaseSetup (этот класс будет использоваться для добавления новых сборок с сущностями, с которыми должен работать NHibernate). 61
80 ПРИЛОЖЕНИЕ B. РУКОВОДСТВО ПОЛЬЗОВАТЕЛЯ FRAMEWORK Создайте новый класс, который будет реализовывать интерфейс InterClientCommunication.Core.Manager.IStorageReaderImplementation (этот класс будет обеспечивать чтение сущностей из хранилища). Создайте новый класс, который будет реализовывать интерфейс InterClientCommunication.Core.Manager.IStorageWriterImplementation (этот класс обеспечит запись сущностей в некоторое хранилище). Классы, реализующие интерфейсы IDatabaseSetup, IStorageReaderImplementation и IStorageWriterImplementation, должны быть зарегистрированы как сервис данного интерфейса в Контейнере (это можно сделать в классе, реализующем интерфейс IContainerInstaller). 4. Реализовать методы, определенные всеми используемыми интерфейсами. 5. При запуске приложения необходимо инициализировать Контейнер, который находится в InterClientCommunication.Core. Инициализация выполняется вызовом статического метода Init, который принимает в качестве параметра объект, реализующий интерфейс IContainerInstaller. 6. Чтобы начать синхронизацию, необходимо инициализировать платформу, вызвав метод Init для объекта класса MainFrameworkController. Сама синхронизация запускается методом StartSync. Экземпляр этого класса необходимо получить с помощью контейнера. B.3 Использование NHibernate и AutoMapper Чтобы настроить AutoMapper, просто создайте классы, наследуемые от класса AutoMapper.Profile, и переопределите метод Configure в этих классах. Конфигурация затем может быть выполнена в этих методах.Классы, созданные таким образом, должны быть зарегистрированы в контейнере как сервис в AutoMapper.Profile. Чтобы использовать NHibernate, просто создайте класс, наследуемый от InterClientCommunication.DataEntities.Daos.NHibernateTransactionalDao или от InterClientCommunication.Server.DataEntities.Daos.NHibernateTransactionalDao. Экземпляр соответствующего класса должен быть создан контейнером IoC. 62
81 Приложение C. Руководство по запуску системы синхронизации файлов В этом руководстве описывается развертывание сервера и запуск приложения синхронизации файлов. C.1 Развертывание сервера Пакет развертывания сервера находится в папке Binary\Server. Минимальные предварительные требования: Microsoft Windows Server 2008 с пакетом обновления 2 (SP2) Microsoft SQL Server 2012.NET Framework 4.5 Включена активация WCF HTTP Веб-сервер Веб-развертывание IIS 7 (можно установить с помощью установщика веб-платформы) Создание базы данных и настройка строки подключения: Создайте базу данных с именем ClientCommunicationDB. Запустите все сценарии, чтобы создать таблицы базы данных из папки базы данных один за другим. Чтобы задать строку подключения для доступа к базе данных, отредактируйте значение параметра Строка подключения MyConnectionString-Web.config в файле InterClientCommunication.Server.SetParameters.xml. Создать хранилище файлов: 63
82 ПРИЛОЖЕНИЕ C. ИНСТРУКЦИИ ПО ЗАПУСКУ СИСТЕМЫ СИНХРОНИЗАЦИИ ФАЙЛОВ Создайте папку ICCServerStorage на диске C. Краткая процедура развертывания приложения на сервере IIS: Запустите командную строку с правами администратора. Запустите InterClientCommunication.Server.deploy.cmd с параметром /T, чтобы проверить, все ли готово к развертыванию. Запустите InterClientCommunication.Server.deploy.cmd с параметром /Y для развертывания на локальном компьютере. Подробные инструкции по развертыванию приложения на сервере IIS можно найти в файле readme. C.2 Запуск клиента Клиентское приложениенаходится в папке Binary\Client. Минимальные предварительные условия: Microsoft Windows Vista SP2.NET Framework 4.5 Запуск приложения: Задайте адрес сервера в файле конфигурации InterClientCommunication.Client.exe.config внутри тега в атрибуте адреса. Включите входящую связь через порт 8000 в брандмауэре (чтобы связь работала в одноранговом режиме). Запустите приложение с правами администратора (для работы одноранговой связи). 64
83 Приложение D Список шагов для тестирования D.1 Инициализация приложения Первый запуск При работающем сервере Без работы сервера Запустить синхронизацию При работающем сервере Без работы сервера Начальная инициализация приложения Создать новый пул клиентов Присоединиться к существующему пулу клиентов Первоначальная инициализация приложения Со значениями по умолчанию порт и путь к синхронизируемой папке С собственными значениями Проверить, сохраняются ли они в памяти даже после перезапуска приложения Г.2 Поиск клиентов С помощью сервера Запуск клиентских приложений с работающим сервером С помощью локальной базы данных 1. Выключить сервер 2. Блокировать многоадресную рассылку по сети 65
84 ПРИЛОЖЕНИЕ D. СПИСОК ШАГОВ ДЛЯ ТЕСТИРОВАНИЯ 3. Запуск клиентских приложений с использованием многоадресной рассылки 1. Выключение сервера 2. Включение отправки многоадресной рассылки по сети 3. Изменение IP-адресов клиентов 4. Запуск клиентских приложений D.3 Базовая синхронизация Подключение нескольких клиентов к одному пулу клиентов. Добавление, изменение, переименование и удаление файла на одном клиенте. Отслеживание влияния изменений на других клиентов. В режиме связи клиент-сервер. В режиме одноранговой связи. взаимодействует Создавать конфликты В режиме связи клиент-сервер (не менее 3) В режиме одноранговой связи Проверять автоматическое разрешение на всех клиентах Разрешать конфликты, возникшие вклиент-серверного режима Использовать все возможные методы решения: Сделать текущим Включить в историю Создать новую сущность (сохранить обе версии) Проверить правильность решения На сервере На всех клиентах Синхронизация больших файлов (около 1 Гб) С работающий сервер без работающего сервера 66
85 D.4. ПЕРЕКЛЮЧЕНИЕ МЕЖДУ РЕЖИМАМИ СВЯЗИ D.4 Переключение между режимами связи Автоматически переключаться в одноранговый режим 1. Отключить сервер 2. Создать/редактировать файлы 3. Разрешить другим устройствам синхронизировать изменения друг с другом Автоматически переключаться в режим клиент-сервер 1. Отключиться некоторые клиенты из сети (но некоторые клиенты должны оставаться подключенными) 2. Подключить сервер 3. Посмотреть историю файлов, загруженных на сервер Сервер получает все данные Все клиенты обновляют базу данных с новым идентификатором сервера 4. Подключить отключенных клиентов 5. Следите за загрузкой остальных данных на сервер и обновлением идентификаторов серверов Переключение в одноранговый режим вручную Проверьте, ведет ли себя так же, как и в случае автоматического переключения Одно устройство в режиме одноранговой связи и другие в режиме клиент-сервер Отслеживание синхронизации от устройства в режиме клиент-сервер к устройству в одноранговом режиме D.5 Функциональность пулов клиентов Две группы клиентов, каждая из которых подключена к другому пулу клиентов Следить не вмешиваясь в синхронизацию второй группы С работающим сервером Без работающего сервера Создание нового пула клиентов С работающим сервером Без работающего сервера для проверки на неисправности Подключение выбранного клиента к новому пулу клиентов С работающим сервером Без работающего сервера для проверки неисправностей Добавление и удаление сущностей из пула клиентов С работающим сервером для мониторинга синхронизации соответствующих сущностей из правильных пулов клиентов (совместное использование сущностей) без работающего сервера, проверка на нефункциональность 67
86ПРИЛОЖЕНИЕ D. ПЕРЕЧЕНЬ ЭТАПОВ ТЕСТИРОВАНИЯ 68
87 Приложение E Документация по интерфейсу связи Интерфейс связи, используемый как на клиенте, так и на сервере, использует протокол связи SOAP. Следующие подразделы содержат только список методов. Более подробное описание методов и их типов данных можно найти в документации по коду на прилагаемом DVD. E.1 Методы интерфейса одноранговой связи Таблица E.1: Список методов интерфейса одноранговой связи Имя GetEntity GetLatestEntities GetPeerInfo GetUtcDateTime HasEntity Ping Описание Получить данные конкретного объекта. Получить последний список сущностей. Получите подробную информацию об одноранговых узлах (идентификатор, конечные точки и т. д.). Получить текущее время UTC с устройства. Проверьте наличие данных сущности. Пустой метод проверки соединения. 69
88 Приложение E. Документация интерфейса связи E.2 Методы интерфейса сервера Таблица E.2: Список методов интерфейса сервера. сущность в указанный пул клиентов. Подключить указанный клиент к указанному пулу клиентов. Создайте новый пул клиентов и добавьте в него выбранного клиента. Создавайте новые сущности. Получить список подключенных пулов клиентов для выбранного клиента. Получить список сведений о клиенте, отфильтрованный по списку пулов клиентов (только клиенты, подключенные к выбранным пулам клиентов). Получите подробную информацию о версии объекта, которая уже есть в истории версий, а также находится в указанном конфликте. Получите конкретные данные объекта. Получить последний список сущностей. Получите последнюю (или самую новую) сущность, включая конкретные данные сущности.Проверьте, присутствуют ли сущность и ее версии на сервере. Пустой метод проверки соединения. Удалить указанный объект из указанного пула клиентов. Разрешить указанный конфликт сущностей. Сохраните новую версию объекта. Обновите сведения о клиенте на сервере. Обновите информацию о клиенте, включая конечные точки на сервере. Загрузить несколько объектов на сервер в виде пакета истории. 70
89 Приложение F Скриншоты примера приложения Рисунок F.1: Экран для первой инициализации приложения 71
90 ПРИЛОЖЕНИЕ F. ОБРАЗЕЦ СКРИНШОТОВ ПРИЛОЖЕНИЯ Рисунок F.2: Главный экран приложения Рисунок F.3: Зеленый значок уведомления с открытым всплывающим окном. Зеленый цвет символа означает, что клиент общается в режиме клиент-сервер. Рисунок F.4: Синий значок уведомления. Синий цвет символа означает, что клиент взаимодействует в одноранговом режиме. 72