In the previous post a .Net Standard library that can be used in .Net Core, UWP and Xamarin apps (last yet to be tested) was presented that implements the device and service functionality of IoT Hub Device Streaming that can be used in UWP and other types apps. This blog discusses the use of the library by the UWP-XAML app in the repository.

The current version of the repository: [djaus2/AziothubDeviceStreaming]{.underline}

Background

Azure IoT Hub Device Streaming, although in Preview, is a cool technology. It enables an IoT device app to receive messages from an app on another system (the service: for example a user app) and for device to respond by sending back a message to the service. An Azure IoT Hub acts as the intermediary in the communications. No modules are needed to be installed in the hub. The functionality is implemented by calls to the IoT Hub SDK by both the device and service apps.

The library AziothubDeviceStreaming refactors the Azure Device Streaming functionality as demonstrated in the IoT Hub SDK Sample, Echo. The GitHub repository, [djaus2/AziothubDeviceStreaming]{.underline} contains the .Net Standard class version of the library. Earlier versions of the repository also contain .Net Core and UWP versions of the library, all using the same refactored source code.. The .Net Standard version though can be used in all .Net SDK contexts. The repository contains a number of sample applications that demonstrate the use of the library as standalone console apps, implemented using the various .Net SDK types (Core, Standard and UWP). Each of these function as one end of the pipe, the service or the device. Typically, an IoT device will perform the device functionality, for example collecting data from sensors. A user app will perform the service end of the pipe. Device Streaming permits a simple method for a user app to get data from a remote IoT device. To run an instance of Device Streaming you install an IoT Hub and run a device and a stream app using the hub’s connection data. The repository also contains a UWP-XAML app, as discussed here.

Default Functionality

To test the functionality of the library, there is a UWP-XAML app (see image below) that can act as both the Device and the Service ends of the pipe. In default mode, a user enters a message in Service-Message-Out and starts its transmission from the Service, press [Send Using Service], which causes a service socket to be created that awaits a connection from a Device. When a Device is instantiated by pressing [Start Listening as Device], it creates a socket when the connection from the service is established and the message reception occurs, with the message displayed in Device-Message-Received. The transmission go-between the service and the device is an Azure IoT Hub for which the connection information is configured in the app. The Device then processes the received message, displays this in Device-Message-Returned and sends it back to the service. The Service receives the message, displays it and closes the socket. Once the device completes its transmission, the device will close its socket. The user can then send subsequent messages, with new instances of the sockets created for the duration of the transmissions and receptions.

Whilst Windows Networking Sockets are used for the service to the IoT Hub communications, the library supports a range of transports between the device and the IoT Hub library, the default being MQTT. The UWP-Xaml app displays the list of available transports in the device section as a menu. The user can make this selection prior to the socket being created at the device end. The transport is a parameter to the device’s socket instantiation.

UWP-XAML App
The UWP-XAML Test App

API Options

The default mode for the AziothubDeviceStreaming library, and for the UWP app is to not keep the sockets alive once communications between both ends for one message are completed. One option with the library and able to be selected by the user in the UWP app, is for the sockets to not be closed after a message’s communications are completed. They then get reused with subsequent communications until closed. This state is re-evaluated with each transmission. There is a Checkbox in the UWP-XAML app for asserting this KeepAlive option.

By default, the Device will echo back the result of its message processing to the Service. With this selected the Service expects a response before closing its socket (KeepAlive false) or before accepting another message to send (KeepAlive true). There is a option in the library to disable this feature in which case the Device receives a message, processes it but does not send a reply. The Service after transmission does not wait for a reply in this mode and either closes the socket or await a new message to send. In the UWP-XAML app there is also a Checkbox to enable this feature (enabled by default)

Note that with both of these options, the choice is made in the Service end and passed along with the message transmitted to the Device. The UWP-XAML app uses example code to add this information at the service end and to extract it at the device end. This optionally prepends some characters to the message in the service and extracts them at the device. This exchange can be customised, as the library just requires some delegates to specified for this functionality.

Socket Timeout and Cancellation

The sockets at both ends are instantiated with a timeout. As configured, the timeouts are both 10,000 milliseconds, i.e. 10 seconds, but can be changed in the UWP-XAML app. For default functionality where messaging is single shot, this is sufficient but need to be increased if the KeepAlive option is taken. If a socket is timed out, there is some clean up and the related functionality can be restarted without consequence.

A typical timeout scenario would be for the device to have a long or infinite timeout. It would to sit and listen for connections, responding to requests then closing and restarting its socket. Alternatively, the device would have a moderate timeout allowing it to periodically restart just in case the device socket gets in an errant condition. The service, running in a user app, would only create a socket when it wants to collect information from the IoT device and so timeout would be relevant with respect to sensing connectivity issues.

The same task cancellation mechanism that is used for Timeout can be manually invoked by pressing the [Cancel] buttons. If in single shot mode, manual cancellation does have not complications. If though in KeepAlive mode, cancelling the device has some rough edges as does manually cancelling the service. (Watch this space).

To Do’s

(i) Currently the UWP-XAML app doesn’t show the status of the sockets. It would be useful if it showed when the device and server sockets were active and when closed. This would be useful for tracking their status, especially with timeouts etc.

(ii) There is significant logging of messages to the Debug window when running in Debug mode from Visual Studio. It is quite instructive to follow these messages whilst testing the library. It might be better to target these messages to a windows in the UWP_XAML app so that they are visible to the user at all time when required. A typical transcript from the Debug window follows:

Using Device Transport Amqp
Using Device Transport Mqtt
Starting Svc TestStream
Svc Stream response received: Name=TestStream IsAccepted=True
Svc Sent stream data: \~Msg Out
Device Received stream data: \~Msg Out
Device Sent stream data: MSG OUT
Closing Device Socket
Svc Received stream data: MSG OUT
Closing Svc Socket

Here’s what displays with a timeout:

Exception thrown: 'System.OperationCanceledException' in System.Private.CoreLib.dll
1 Error RunDeviceAsync(): Operation canceled 
Aborted

 TopicSubtopic
  Next: > AziothubDeviceStreaming
<  Prev:   AziothubDeviceStreaming
This Category:Azure Device Streaming
  Next: > AziothubDeviceStreaming Under the hood-The API 
<  Prev:   AziothubDeviceStreaming