AziothubDeviceStreaming: Azure IoT Hub Device Streaming - A Reusable and Extensible Library
azure azure iothub csharp uwp dnetcore device service streaming
In the previous post, some issues were raised wrt refactoring of the Azure IoTHub SDK Device Streaming Echo sample functionality as .Net Core and UWP reusable libraries. These issues have been resolved and the library is now presented as a .Net Standard library that can be used in .Net Core, UWP and Xamarin apps (last yet to be tested). The library implements the device and service functionality of IoT Hub Device Streaming that can be used in UWP and other types apps.
We have a solution!
The main problem, as discussed previously, was that the developed Device Streaming library, regardless of the SDK .Net Framework used (UWP, .Net Core or .Net Standard), did not support the AMQP transport (Device-IoTHub) when used with a UWP app. It was determined that the Nuget installation of Microsoft.Azure.Device.Client (Device Streaming requires the latest preview version) implicitly installed an earlier version of Microsoft.Azure.Ampq 2.3.7, whereas version 2.4.2 was required. This was resolved by explicitly installing Microsoft.Azure.Amqp version (2.4.2) using Nuget.
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.
I’ve developed a GitHub C# Library project for UWP Sockets: djaus2/SocketsUWP. With THIS new repository, I am attempting to use Azure IoTHub as the conduit in new library that mimics the socket stream functionality.
Whereas the previous version of the repository, implemented all three types of .Net libraries, the new version only implements the .Net Standard version as this can be used universally. The various types of test apps remain in the repository. The UWP app have been significantly extended to test some added features of the library:
- The original communications were single shot. The service create a socket send a message waits for a reply then closes the socket. The device listens for a connection, create a socket, reads teh message, processes it and sends it back. It then closes its socket. Whilst this is the default behaviour with the new version of the library, there is a Keep Alive option that keeps the sockets open at both ends, subject to timeout, until closed. This option is dictated by the Service end.
- The original device processing required a response to be sent back. For this repository the received message was uppercased. (The SDK Echo Sample app just sent back the received message). This is now optional, and is dictated by the Service end.
- The uppercase functionality is now actually implemented via a delegate in the device app and so that functionality is simple to change, to sya, reading some sensors.
- Whilst not 100% debugged, there is now an option to cancel the socket at either end.
Overall,the object here is to to create a conceptually high level library that encapsulates the Azure IoTHub Device Streaming functionality which is simple to use, but contains inbuilt extensibility (read options) that can be exploited in host apps without reconstruction of the library.
The GitHub Repository
The GitHub repository for this project: djaus2/AziothubDeviceStreaming
The repository projects.
The Device Streaming functionality is now implemented in just one .Net Standard library, AzDeviceStreaming. There are three sets of Device and Service apps, as per the class library projects they use:
- .Net Core
- .Net Standard
- UWP (.Net Framework)
All apps now use the same .Net Standard AzDeviceStreaming library.
The original Sample Azure IoTHub Device Streaming apps are included as standalone .NetCore apps. There is some slight modification of the given code but it essentially as supplied on GitHub (except for two changes as noted below.))
The 3 original source code files from the Echo Sample are located in the folder common off the Solution folder. These are used with modifications in the library.
The device functionality with the SDK’s sample DeviceStreaming apps is to just echo back the message received. In this suite of apps, the device uppercases the received string and sends that back to the service. This functionality is implemented in the AzDeviceStreaming class library,
Why so many projects?
With this suite of C# projects you can test the Azure IoT Hub Device Streaming with various combinations of versions of apps (device and streaming). The UWP app can simultaneously perform both ends of the pipe and also demonstrates that additional features.
- The repository for this project: djaus2/AziothubDeviceStreaming
- The Az IoTHub SDK Device streaming Echo qucikstart sample
- Az IoT Hub Device Streams Overview
- There is also a Device Streaming Proxy example (not discussed here, yet) where an arbitrary port on the client side can be funneled to the IoTHub using SSLs
For this suite of projects I am refactoring the Echo Example into a library that can be used in UWP apps.
Both libraries are now .Net Standard. There are .NetCore, .NetStandard and UWP(.Net Framework) app projects, all of which use the .Net Standard libraries.
- Both are .Net Standard
The AzDeviceStreams class library contains the Azure IoTHub SDK functionality as refactored from the original sample apps.
The AzConnections contains the IoT Hub connectivity settings:
- IoT Hub Connection string
- IoT Hub Device Connection string
- IoT Hub Device Id (Eg “MyDevice”)
These are blank strings in the repository. You can then set up one Az IoT Hub, set up one device for it, and that can then be used throughout all projects.
The AzConnections also contains sample code for implementing some of the new optional features, as discussed in the next blog.
- .Net Core
- .Net Standard
.Net Core Apps
To run in .NetCore mode set the target to AnyCPU. Only the .Net Core apps and the libraries get built.
The apps for the .NetCore target are exactly the same as the device and server apps in the Echo Quickstart except that:
- The IoT Hub functionality is removed and encapsulated in the AzDeviceStreams class libraries.
- A callback delegate is used to pipe received messages to the app.
- The app calls the library’s API to send a message back
- The device functionality echoes back the string to the service in uppercase
- There are two code improvements as discussed later.
Once the IoT Hub is set up you can run both apps simultaneously on the the same system, mix and match with the .Net Standard and UWP apps. (One device and one service required).
.Net Standard Apps
As per .Net Core
To run in UWP mode set the target for the target system’s CPU (x86,x64 etc). Only the UWP apps and the .Net Standard libraries get built in this mode.
Implements both the Device and Service functionality
Implements the Device functionality as a UWP console app.
Implements the Device functionality as a UWP console app.
Implements the Device functionality as a UWP Background Task. Runs only on IoT-Core
Implements the Service functionality as a UWP Background Task. Runs only on IoT-Core
- Setup and Azure IoT Hub and add a device to it as per the [QuciskStart]((https://docs.microsoft.com/en-us/azure/iot-hub/quickstart-device-streams-echo-csharp/?WT.mc_id=IoT-MVP-5000301)
- Get the Connection strings (both) and the DeviceId
- Edit one AzureConnections class (only one as they all use teh same source code).
- Set the Target and build
- Run any pair of apps (Device and Stream) .Nb the UWPXamlApps can perform both ends
Note that if run from Visual Studio, there are extensive debug messages informing of the app’s progress.
- In RunSvcAsync() it was found that a call to close the stream was required. The Device reported that the socket was not closed properly at the other end.
The following was added at the end of the
using (var stream = await DeviceStreaming ...segment just before the closing brace:
await stream.CloseAsync(WebSocketCloseStatus.NormalClosure, String.Empty, cancellationTokenSource.Token).ConfigureAwait(false);
|This Category Links|
|Category:||Azure Device Streaming Index:||Azure Device Streaming|
|Next: >||AziothubDeviceStreaming||The UWP-XAML app V1|
|< Prev:||AziothubDeviceStreaming||Azure IoT Hub Device Streaming|