Communicate with a remote app service

In addition to launching an app on a remote device using a URI, you can run and communicate with app services on remote devices as well. Any Windows-based device can be used as either the client or host device. This gives you an almost limitless number of ways to interact with connected devices without needing to bring an app to the foreground.

Set up the app service on the host device

In order to run an app service on a remote device, you must already have a provider of that app service installed on that device. This guide will use CSharp version of the Random Number Generator app service sample, which is available on the Windows universal samples repo. For instructions on how to write your own app service, see Create and consume an app service.

Whether you are using an already-made app service or writing your own, you will need to make a few edits in order to make the service compatible with remote systems. In Visual Studio, go to the app service provider's project (called "AppServicesProvider" in the sample) and select its Package.appxmanifest file. Right-click and select View Code to view the full contents of the file. Create an Extensions element inside of the main Application element (or find it if it already exists). Then create an Extension to define the project as an app service and reference its parent project.

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

Next to the AppService element, add the SupportsRemoteSystems attribute:

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

In order to use elements in this uap3 namespace, you must add the namespace definition at the top of the manifest file if it isn't already there.

<?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>

Then build your app service provider project and deploy it to the host device(s).

Target the app service from the client device

The device from which the remote app service is to be called needs an app with Remote Systems functionality. This can be added into the same app that provides the app service on the host device (in which case you would install the same app on both devices), or implemented in a completely different app.

The following using statements are needed for the code in this section to run as-is:

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

You must first instantiate an AppServiceConnection object, just as if you were to call an app service locally. This process is covered in more detail in Create and consume an app service. In this example, the app service to target is the Random Number Generator service.

Note

It is assumed that a RemoteSystem object has already been acquired by some means within the code that would call the following method. See Launch a remote app for instructions on how to set this up.

// 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"
    };

Next, a RemoteSystemConnectionRequest object is created for the intended remote device. It is then used to open the AppServiceConnection to that device. Note that in the example below, error handling and reporting is greatly simplified for brevity.

// 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;
}

At this point, you should have an open connection to an app service on a remote machine.

Exchange service-specific messages over the remote connection

From here, you can send and receive messages to and from the service in the form of ValueSet objects (for more information, see Create and consume an app service). The Random number generator service takes two integers with the keys "minvalue" and "maxvalue" as inputs, randomly selects an integer within their range, and returns it to the calling process with the key "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;
    }
}

Now you have connected to an app service on a targeted host device, run an operation on that device, and received data to your client device in response.

Connected apps and devices (Project Rome) overview
Launch a remote app
Create and consume an app service
Remote Systems API reference
Remote Systems sample