The classic LED blinking app controlled by another app's WebServer.
We’ll create a simple Blinky app controlled by another app’s WebServer and connect a LED to your MinnowBoard Max (or MBM for short).
You can find this sample in the Samples\App2App WebServer folder.
Make sure you set the ‘Remote Debugging’ setting to point to your MBM. Go back to the basic ‘Hello World’ sample if you need guidance.
Make sure you connect the LED to your MBM. Go back to the basic ‘Blinky’ sample if you need guidance.
We are demonstrating two ideas with this sample: how to implement a WebServer and how to enable app-to-app communication. To demonstrate this, the sample contains:
WebServerApp - this project registers a BackgroundTask which provides a web server and hosts an app-to-app communication service.
BlinkyApp - this is a UAP app similar to the Blinky sample app except that the LED power state is controlled by the webserver.
To create a WebServer that can communicate with our Blinky app, we need to do two things: implement an actual
server and enable app-to-app communication. At the core of our server implementation is a ‘StreamSocketListener’.
Here is a simplified version of what we need to implement this:
public sealed class HttpServer : IDisposable
{
public void StartServer(int port)
{
// Create and bind our StreamSocket to a port and process
// requests as they arrive
StreamSocketListener listener = new StreamSocketListener();
listener.BindServiceNameAsync(port.ToString());
listener.ConnectionReceived += (s, e) =>
{
// Read request from the socket
using (IInputStream input = e.Socket.InputStream)
{
. . .
await input.ReadAsync(buffer, BufferSize, InputStreamOptions.Partial);
. . .
}
// Parse request and compose response
. . .
// Write response to the socket
using (IOutputStream output = socket.OutputStream)
{
using (Stream resp = output.AsStreamForWrite())
{
// Update the WebServer client
. . .
}
}
}
}
}
}To be allowed to function as a server, we need to add a new capability to the Package.appxmanifest:
<Capabilities>
<Capability Name="internetClient" />
<Capability Name="internetClientServer" />
</Capabilities>To be allowed to communicate with other apps, we need to add some special configuration to Package.appxmanifest. Specifically, we to add the extension: ‘windows.appService’. This extension requires two pieces of information:
These properties can be modified like this:
<Applications>
<Application Id="App">
. . .
<Extensions>
<uap:Extension Category="windows.appService" EntryPoint="WebServerTask.WebServerBGTask">
<uap:AppService Name="Ap2AppComService" />
</uap:Extension>
</Extensions>
</Application>
</Applications>At this point, all of the requisite building blocks have been established. We can focus on putting them together. First, our BackgroundTask must be implemented. A BackgroundTask is a simple implementation of the IBackgroundTask interface which consists of a ‘Run’ method. The implementation of our WebServer and app-to-app communication must begin in this method.
For our WebServer, our BackgroundTask must instantiate our WebServer and implement our app-to-app communication.
BackgroundTaskDeferral _serviceDeferral;
public void Run(IBackgroundTaskInstance taskInstance)
{
// Get the deferral object from the task instance
_serviceDeferral = taskInstance.GetDeferral();
var appService = taskInstance.TriggerDetails as AppServiceTriggerDetails;
if (appService != null && appService.Name == "Ap2AppComService")
{
// Start our WebServer asynchronously
HttpServer server = new HttpServer();
IAsyncAction asyncAction = Windows.System.Threading.ThreadPool.RunAsync(
(workItem) =>
{
// We can pass our AppServiceConnection instance to the WebServer to
// allow it to participate in the app-to-app communication
server.StartServer(appService.AppServiceConnection);
});
// Implement the app-to-app communication service request listener
appService.AppServiceConnection.RequestReceived += (sender, args) =>
{
var message = args.Request.Message;
// We can handle various requests from other apps here and respond using
// 'await args.Request.SendResponseAsync'
. . .
};
}
}The client app is very similar to the Blinky sample. The major addition here is that we are allowing a WebServer to be used to configure the on/off state for our LED. To establish a connection with the WebServer app via the app-to-app mechanism, we need to create an AppServiceConnection object, configure it with information from the WebServer app, and send/receive messages.
// Initialize the AppServiceConnection
AppServiceConnection appServiceConnection = new AppServiceConnection();
// Provide the PackageFullName of the WebServerApp
appServiceConnection.PackageFamilyName = "WebServer_hz258y3tkez3a";
// Provide the AppService Name specified in WebServerApp's Package.appxmanifest
appServiceConnection.AppServiceName = "Ap2AppComService";
// Establish the app-to-app connection
var res = await appServiceConnection.OpenAsync();
if (res == AppServiceConnectionStatus.Success)
{
appServiceConnection.RequestReceived += (sender, args) =>
{
// Messages received can be handled here as needed
. . .
};
// We can send messages via 'appServiceConnection.SendMessageAsync'
. . .
}To get the Blinky WebServer running, first deploy the WebServer project. This will register the app-to-app communication mechanism. Then deploy and run the Blinky project. This will start our headed Blinky app and initialize and start the app to app communication (which will also start the web server). You can then test it all with the web client as detailed in the next step.
For our sample app, we have hosted a simple client in our WebServer. It can be accessed via the IP address and port (something like http://10.0.0.1:8000) and can be used to toggle the LED on and off

As always, for questions and feedback, contact us.