Мобильные сервисы, блобы и Windows 8. Храним данные в облаке

от автора

Добрый день.

Мы живем в мире тотальной глобализации как в реальной жизни, так и в виртуальной. Я имею в виду, что нам хочется иметь одни и те же данные, одни и те же настройки и одно и то же поведение программ на разных устройствах. Такой синхронизации всего и вся в наше время легко добиться с помощью облаков. Об этом и пойдет речь в данной статье, а именно о скрещивании приложения для Windows 8 (WinRT) с облаком Windows Azure для хранения данных и метаданных.

Вводная

Итак, предположим, что у нас есть приложение для Windows 8 (пусть это будет сервис хранения неких текстовых записей), которое:
1) Должно отображать список записей с минимальной информацией о каждой из них (допустим, заголовок или дату создания). Назовем это метаданными.
2) Должно иметь возможность показать подробную информацию о записи (контент) при переходе к конкретному элементу. Назовем это данными.
3) Должно синхронизировать данные между различными устройствами под управлением Windows 8 (создал запись дома, просмотрел ее же на работе).

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

По ходу этой статьи мы познакомимся с Windows Azure Mobile Services для хранения метаданных и Windows Azure Blob Storage для хранения данных. Впереди много текста и картинки.

Шаг 1. Работа с облачным хранилищем

Для более гибкой и кроссплатформенной работы с Windows Azure Blob Storage я дополнительно рекомендую ввести еще один слой в виде WCF-сервиса, который будет получать и обрабатывать запросы от мобильных клиентов. Поэтому первый шаг данного руководства будет состоять из нескольких этапов.

Создание нужных нам сервисов Windows Azure

Для начала нам необходимо подготовить облачное окружение, создав в Windows Azure две службы — Cloud Service и Storage. Начнем со второго. Заходим в портал управления Windows Azure. Внизу страницы есть большая кнопка с плюсом. По нажатии откроется выбор сервисов для создания. Нам нужен DATA SERVICES -> STORAGE:

Вводим любое удобное для нас имя нового сервиса, нажимаем кнопку-галку внизу и ждем, пока сервис не получит статус Online. После этого заходим в настройки нашего хранилища и ищем глазами и мышкой кнопку «Mange keys» с иконкой буквы i на борту. Нажимаем на нее и видим перед собой три поля. В первом будет находиться имя данного сервиса, который мы ему присвоили при создании, а во втором и третьем будут храниться ключи доступа. Запомним первый из них, он нам пригодится уже скоро.

Создание WCF сервиса

Для создания WCF сервиса и соотвествующей ему службы в Windows Azure мы воспользуемся Visual Studio 2012. Я буду показывать на примере версии Ultimate, но для бесплатного использования подойдет версия Web.
Итак, открываем студию и создаем новый проект с типом Cloud:

В появившемся окне нам будет предложено выбрать типы проектов, которые надо разместить в облаке. Нас интересует WCF Service Web Role. Выбираем его и добавляем к списку создаваемых (не забываем переименовать):

Visual Studio, после недолгих раздумий, создаст для нас два проекта, один из которых будет проектом WCF службы, а второй — специальный проект для публикации в облако Windows Azure. Давайте немного их понастраиваем.

Чтобы безболезненно публиковать наш сервис в облако, Visual Studio должна знать, в какое именно облако ей это делать, а также понимать, что мы имеем на это право. Чтобы ее убедить, достаточно нажать правой кнопкой мыши на проекте Cloud и выбрать пункт меню Publish:

Если вы ранее не публиковали ничего в облако, то вместо значения WindowsAzureMSDN у вас будет пусто. Чтобы было густо, достаточно перейти по ссылке, скачать профиль публикаций и испортировать его с помощью кнопки Import в Visual Studio. Это позволит вам выполнять операции над облачными сервисами прямо из IDE.

После того, как у нас появился доступ к облаку из VS2012, переходим на следующий шаг, где создадим непосредственно Cloud Service для хостинга нашей WCF-службы. На вкладке Common Settings выбираем Cloud Service -> Create New, а на вкладке Advanced Settings указываем существующий Storage Account (он должен уже быть доступным для выбора в списке). Старайтесь, чтобы и Cloud Service и Storage Account были в одной зоне:

После выполнения этих действий нам достаточно просто нажать кнопку Publish, и проект утечет в сеть.

Шаг 2. Использование хранилища

Первым делом надо добавить строку соединения в файл web.config нашего сервиса. Строка выглядит следующим образом:
DefaultEndpointsProtocol=https;AccountName=имя_сервиса;AccountKey=тот_самый_ключ_от_Storage

Работа с облачным хранилищем может осущетсвляться двумя способами — с помощью REST API и с помощью .NET обертки. В данной статье я буду использовать второй вариант как наиболее простой. Тем более не зря же мы создавали свой собственный сервис.

Итак, для того, чтобы пользоваться данным функционалом, надо подключить к своему проекту NuGet пакет «Windows Azure Storage»:

Подключение и управление BLOB-контейнерами происходит с помощью клиента:

using Microsoft.WindowsAzure.Storage; using Microsoft.WindowsAzure.Storage.Blob;  CloudStorageAccount storageAccount = CloudStorageAccount.Parse(_connectionString); _blobClient = storageAccount.CreateCloudBlobClient(); 

Дальнейшая работа с хранилищем довольно проста:

// Получение контейнера CloudBlobContainer container = BlobClient.GetContainerReference(ContainerName); // Создание, если его не существует container.CreateIfNotExists(); // Получение блока по принципу "префикс-<id записи>" CloudBlockBlob blockBlob = container.GetBlockBlobReference(BlobNamePrefix + data.Id);  // Сериализуем данные var serializer = new XmlSerializer(typeof(CompositeType)); using (var s = new MemoryStream()) {     serializer.Serialize(s, data);     s.Seek(0, SeekOrigin.Begin);      // И пишем в blob     blockBlob.UploadFromStream(s); } 

Аналогично данные можно получить:

// Получение контейнера CloudBlobContainer container = BlobClient.GetContainerReference(ContainerName); // Если не существует - возвращаем null if (!container.Exists())     return null;  // Так же пытаемся получить блок var blockBlob = container.GetBlockBlobReference(BlobNamePrefix + id); if (!blockBlob.Exists())     return null;  // И десериализуем бинарные данные var serializer = new XmlSerializer(typeof(CompositeType)); CompositeType result = null;  using (var s = new MemoryStream()) {     // Скачиваем данные из блоба     blockBlob.DownloadToStream(s);     s.Seek(0, SeekOrigin.Begin);     result = serializer.Deserialize(s) as CompositeType; }  return result; 

Вышеописанные методы были помещены в класс обертку, а сам WCF-сервис обаладает простым контрактом из двух действий:

[ServiceContract] public interface IBlobService {     [OperationContract]     CompositeType GetData(int value);      [OperationContract]     void PutData(CompositeType data); } 

!!! Тут надо упомянуть важную, но абсолютно неочевидную вещь. Имена блоб контейнеров и блоков должны быть в маленьком регистре. То есть имя BlobContainer вызовет ошибку при попытке создания, а, например, blob-container создастся без проблем.

После того, как мы написали сервис, еще раз публикуем его в облако и после завершения этой процедуры он будет доступен по адресу ваше_имя_сервиса.cloudapp.net/BlobService.svc.

Шаг 3. Мобильные сервисы

Предыдущие два шага были направлены на создание инфраструктуры для хранения «данных» — информации большого объема, которая нужна не всегда, а по запросу. Теперь давайте перейдем к хранению «метаданных». Для этого мы воспользуемся недавней новинкой в Windows Azure — Mobile Services.

Создать новый мобильный сервис так же просто, как и остальные услуги в Windows Azure. Опять идем на портал управления, где внизу в меню создания выбираем COMPUTE -> MOBILE SERVICE и видим перед собой мастер:

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

Как только сервис будет создан, переходим на его страницу в раздел, помеченный иконкой облака с молнией (названия у него я не знаю). На этой странице есть две опции — Create a new Windows Store app и Connect an existing Windows Store app. Первая позволит вам скачать архив с приложением, настроенным для работы с вашим мобильным сервисом, а вторая просто даст кусочек кода, который надо внедрить в существующее приложение. В принципе сейчас не важно, какую опцию вы выберете. Я предлагаю использовать вторую и создать приложение вручную.

А пока мы этого не сделали, давайте подготовим Mobile Services к использованию. Для этого сперва пеерйдем в раздел Data (в верхнем меню) и добавим новую таблицу для хранения записей. Назвать можно как угодно, у меня — TestItem:

В этой таблице впоследствии будут размещаться записи метаданных, введенные в приложении для Windows 8.

Шаг 4. Windows 8

Настало время сделать то, ради чего все затевалось. Приложение для Windows 8 (WinRT) можно бесплатно создать в Express версии Visual Studio 2012 (наподобие той, что мы использовали для WCF сервиса, но теперь для Win8 приложений).
File -> New Project -> Windows Store:

Сперва надо добавить необходимые ссылки на библиотеки, чтобы можно было пользоваться благами Mobile Services. Если вы обратили внимание, то на предыдущем шаге Windows Azure предалал нам скачать и установить Mobile Services SDK. Это нужно сделать, ибо с его помощью мы будем работать с облачными сервисами для мобильных устройств.

Как только SDK установлен, мы можем подключить его к проекту с помощью стандартной процедуры Add Reference:

Затем подключим еще и ссылку на наш WCF сервис. Делается это также несложно с помощью стандартного диалога Add Service Reference:

В результате подключения Service Reference Visual Studio создаст для нас специальный класс обертку, который будет выглядеть как обычный класс с контрактом сервиса, но на самом деле будет обращаться к удаленному WCF по указанному адресу.

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

public static MobileServiceClient MobileService = new MobileServiceClient(             "https://***.azure-mobile.net/",             "secret_key"); 

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

Шаг 5. Собираем все вместе

Настало время соединить все пути в одной точке и написать код, который при добавлении новой записи будет размещать ее в хранилище Azure Blob Storage и Mobile Services.

private async Task PutDataTestWCF(CompositeType data) {     // Получаем клиент для работы с WCF     var cli =         await         Task.Run(() => new BlobServiceClient(new BasicHttpBinding(), new EndpointAddress(CloudServiceEndpoint)));     // Вызываем сгенеренный метод добавления данных (асинхронный)     await cli.PutDataAsync(data);     // Не забываем закрыть клиент     await cli.CloseAsync();      // Получаем таблицу в мобильных сервисах     var table = App.MobileService.GetTable<TestItem>();     // Выбираем из нее записи     var list = await table.Select(x => x.Id == data.Id).ToListAsync();      // Если такая запись есть, то делаем обновление, иначе - вставку     if (list != null && list.Count > 0)         await table.UpdateAsync(new TestItem() {Id = data.Id, Text = data.Text});     else         await table.InsertAsync(new TestItem() {Text = data.Text}); } 

Тут стоит обратить внимание на несколько вещей. Во первых, все методы, которые так или иначе работают с сетью, являются асинхронными. Даже класс клиента к WCF сервису, который сгенерировался автоматически, тоже содержит асинхронные методы (PutDataAsync). Это здорово, поскольку позволяет делать приложение более отзывчивым, не заставляя пользователя наблюдать заблокированный интерфейс, пока приложение пытается соединиться с Интернетом.
Помимо этого, работа с обоими сервисами стала довольно простой и прозрачной. Что работа с WCF, что с Mobile Services, обе они выглядят как простые вызовы .Net кода, скрывая все детали «где-то там». Я не писал здесь никаких абстрактных слоев доступа к данным, но если заморочиться и сделать все грамотно, то мы сможем легко делать заглушки и моки (mock) для тестирования приложения.

Заключение

В этой статье в первую очередь я хотел показать не как писать Windows 8 приложения, а как встроить в них возможность работы с различными типами облачного хранилища разлиными способами. Я сознательно привел не так много кода, поскольку статья и так получилась большой и, возможно, сложной для восприятия. Ниже я прилагаю архив с кодом, который можно использовать для тренировки:
Скачать архив
В нем я заменил все упоминания своего сервиса на *** или ****. Думаю будет понятно, что и куда надо подставить, чтобы все взлетело.

При подготовке статьи и тестового приложения были использованы следующие материалы:
Официальное руководство по работе с Blob Storage
Официальное руководство по работе с данными в мобильных сервисах
Google, Bing, Yandex
— Собственные мысли и догадки

P.S. Большая просьба к неравнодушным минусаторам — пишите, пожалуйста, аргументацию своих минусов или в комментах, или в личку. Мне важно знать свои огрехи, чтобы исправлять их в будущих публикациях. Спасибо большое.

ссылка на оригинал статьи http://habrahabr.ru/post/157641/


Комментарии

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

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