Blazor-IoT: Azure IoT Hub Interaction using Blazor on a RPi - Some Hacks ... and a Solution.
Some attempts at getting around the inability of the Blazor Client app to directly interact with sensors.
The previous two posts considered the question. “Can the Client end of a Blazer WASM app use sensors attached to it for forwarding data to IoT hub via the Blazor Service?”. it was found that because the client end is effectively a browser and therefore a sandbox, the client in cannot interact with hardware. It can’t use the APIs on GitHub at dotnet/iot, specifically the System.Device.GPIO library. This post considers whether there are any workaround for this.
The next post covers another Blazor WASM app for simulating an Azure IOT Hub Device. In the client you select the device’s sensor type and enter the sensor value (or values for a multidimensional sensor). The service sends the sensor data to an IoT Hub via on behalf of the client. The idea was that if the GPIO library could be accessed from the Blazor WASM client, then the client could act as a real IoT Hub Device. But, because of the previous posts, we are left with only simulation. But what if the this client was able to communicate directly with a sensor on its host being interrogated by a .NET Core Console app there, through an enabling medium? The plot thickens!
Perhaps a .Net Core Console app that can access sensors on the client device could pass the data to the client somehow? This would run an app such as this: Device Message Sample in Azure IoT Hub SDK
The first “fix” attempted was to make Http calls from the .Net Core Console app, with a complete path that included the sensor type and sensor value/s as path parameters to a Http GET. Essentially making the GET call that the Blazor WASM Client makes to the Service. That just returns the client’s error page. .
Another approach envisaged was the use of a Blazor API that can save data to local data on the client. You can read and write data to/from the client app. The idea was that if this could be accessed by the console app on the client’s host then the console app could be the writer of sensor data and the Blazor Client app could be the reader. This library is on GitHub at Blazored/LocalStorage. Chris Sainty has contributed a lot to Blazor. To quote Chris: “This isn’t possible. Local storage is a browser feature and can’t be accessed by anything except the browser as this would be a huge security flaw”.
Another possible attempt
Maybe a service could be added to pass data between apps but I suspect that won’t work for similar reasons. Also a serial pipe between the two would run up against GPIO issues with the client. Some of these approaches seem rather convoluted. May as well just have the console app using the Azure IoT Hub directly.
Finally .. this worked: Http PUT
OK so the Console app can’t do a Http Client Get with SensorType and Data as parameters. So what if we did a direct call to the service using a Http PUT?
var dataAsString = JsonConvert.SerializeObject(Sensor); var content = new StringContent(dataAsString); content.Headers.ContentType = new MediaTypeHeaderValue("application/json"); var resultPost = await httpClient.PostAsync(url, content);
Where url is
<Blazor Service Url>/Sensor for example
<Blazor Service Url> is the Url of the app in the next blog post.
Sensor is the Controller on that server that handles the POST.
Console.WriteLine(resultPost.StatusCode.ToString()); var sr = await resultPost.Content.ReadAsStringAsync(); Console.WriteLine(sr);
And that all worked!
|This Category Links|
|Next: >||Publishing Blazor to Desktop IIS|
|< Prev:||Blazor-IoT||Azure IoT Hub Interaction using Blazor on a RPi - GPIO and Bindings App|