Добрый день.
Мы живем в мире тотальной глобализации как в реальной жизни, так и в виртуальной. Я имею в виду, что нам хочется иметь одни и те же данные, одни и те же настройки и одно и то же поведение программ на разных устройствах. Такой синхронизации всего и вся в наше время легко добиться с помощью облаков. Об этом и пойдет речь в данной статье, а именно о скрещивании приложения для 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 для
После выполнения этих действий нам достаточно просто нажать кнопку 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. Большая просьба к неравнодушным минусаторам — пишите, пожалуйста, аргументацию своих минусов или в комментах, или в личку. Мне важно знать свои огрехи, чтобы исправлять их в будущих публикациях. Спасибо большое.
Автор: glamcoder