Обмен данными с удаленной службой приложений

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

Настройка службы приложений на главном устройстве

Чтобы запустить службу приложений на удаленном устройстве, необходимо, чтобы на нем уже был установлен поставщик этой службы приложений. В этом руководстве используется версия образца службы приложений "генератор случайных чисел" на CSharp, которая доступна в репозитории примеров универсальных приложений Windows. Инструкции по созданию собственной службы приложений см. в разделе Создание и использование службы приложений.

Используется ли готовая служба приложения или создается собственная служба, необходимо внести несколько изменений, чтобы сделать службу совместимой с удаленными системами. В Visual Studio перейдите в проект поставщика службы приложения (в примере он называется AppServicesProvider) и выберите соответствующий файл Package.appxmanifest. Щелкните правой кнопкой мыши и выберите Перейти к коду для просмотра всего содержимого файла. Создайте элемент Extensions внутри элемента main Application (или найдите его, если он уже существует). Затем создайте расширение , чтобы определить проект как службу приложений и сослаться на его родительский проект.

...
<Extensions>
    <uap:Extension Category="windows.appService" EntryPoint="RandomNumberService.RandomNumberGeneratorTask">
        <uap3:AppService Name="com.microsoft.randomnumbergenerator"/>
    </uap:Extension>
</Extensions>
...

Рядом с элементом AppService добавьте атрибут SupportsRemoteSystems :

...
<uap3:AppService Name="com.microsoft.randomnumbergenerator" SupportsRemoteSystems="true"/>
...

Чтобы использовать элементы в этом пространстве имен uap3 , необходимо добавить определение пространства имен в начало файла манифеста, если оно еще не существует.

<?xml version="1.0" encoding="utf-8"?>
<Package
  xmlns="http://schemas.microsoft.com/appx/manifest/foundation/windows10"
  xmlns:mp="http://schemas.microsoft.com/appx/2014/phone/manifest"
  xmlns:uap="http://schemas.microsoft.com/appx/manifest/uap/windows10"
  xmlns:uap3="http://schemas.microsoft.com/appx/manifest/uap/windows10/3">
  ...
</Package>

Затем создайте проект поставщика службы приложений и разверните его на ведущих устройствах.

Выбор службы приложений с клиентского устройства

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

Чтобы код из этого раздела работал в приведенном виде, необходимы следующие операторы using:

using Windows.ApplicationModel.AppService;
using Windows.System.RemoteSystems;

Сначала необходимо создать экземпляр объекта AppServiceConnection, точно так же, как и при локальном вызове службы приложения. Этот процесс подробно описан в разделе Создание и использование службы приложений. В этом примере в качестве целевой службы приложений используется служба генератора случайных чисел.

Примечание

Предполагается, что объект RemoteSystem уже каким-то образом получен в коде, который будет вызывать следующий метод. Инструкции относительно того, как это сделать, см. в разделе Запуск удаленного приложения.

// This method returns an open connection to a particular app service on a remote system.
// param "remotesys" is a RemoteSystem object representing the device to connect to.
private async void openRemoteConnectionAsync(RemoteSystem remotesys)
{
    // Set up a new app service connection. The app service name and package family name that
    // are used here correspond to the AppServices UWP sample.
    AppServiceConnection connection = new AppServiceConnection
    {
        AppServiceName = "com.microsoft.randomnumbergenerator",
        PackageFamilyName = "Microsoft.SDKSamples.AppServicesProvider.CS_8wekyb3d8bbwe"
    };

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

// a valid RemoteSystem object is needed before going any further
if (remotesys == null)
{
    return;
}

// Create a remote system connection request for the given remote device
RemoteSystemConnectionRequest connectionRequest = new RemoteSystemConnectionRequest(remotesys);

// "open" the AppServiceConnection using the remote request
AppServiceConnectionStatus status = await connection.OpenRemoteAsync(connectionRequest);

// only continue if the connection opened successfully
if (status != AppServiceConnectionStatus.Success)
{
    return;
}

На этом этапе у вас должно иметься открытое подключение к службе приложений на удаленном компьютере.

Обмен специфичными для службы сообщениями по удаленному подключению

Отсюда можно отправлять в службу и получать из службы сообщения в форме объектов ValueSet (дополнительные сведения см. в разделе Создание и использование службы приложения). Служба генератора случайных чисел принимает 2 целых числа с ключами "minvalue" и "maxvalue" в качестве входных данных, случайным образом выбирает целое число внутри диапазона и возвращает это число в вызывающий процесс с ключом "Result".

    // create the command input
    ValueSet inputs = new ValueSet();

    // min_value and max_value vars are obtained somewhere else in the program
    inputs.Add("minvalue", min_value);
    inputs.Add("maxvalue", max_value);

    // send input and receive output in a variable
    AppServiceResponse response = await connection.SendMessageAsync(inputs);

    string result = "";
    // check that the service successfully received and processed the message
    if (response.Status == AppServiceResponseStatus.Success)
    {
        // Get the data that the service returned:
        result = response.Message["Result"] as string;
    }
}

Теперь вы подключены к службе приложений на целевом главном устройстве, выполнили операцию на этом устройстве и получили данные на клиентском устройстве в ответном сообщении.

Обзор подключенных приложений и устройств (Project Rome)
Запуск удаленного приложения
Создание и использование службы приложений
Справочник по API удаленных систем
Пример удаленных систем