Skip to content
This repository has been archived by the owner on Nov 16, 2023. It is now read-only.

Commit

Permalink
Merge pull request #172 from Azure-Samples/drwill/ReadD2cMessages
Browse files Browse the repository at this point in the history
Cleanup ReadD2cMessages sample
  • Loading branch information
David R. Williamson authored Dec 10, 2020
2 parents 98ac09e + 49ee93c commit 042befa
Show file tree
Hide file tree
Showing 13 changed files with 269 additions and 172 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp2.1</TargetFramework>
<TargetFramework>netcoreapp3.1</TargetFramework>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.Azure.Devices" Version="1.*" />
<PackageReference Include="Microsoft.Azure.Devices" Version="1.28.1" />
</ItemGroup>

</Project>
87 changes: 87 additions & 0 deletions iot-hub/Quickstarts/InvokeDeviceMethod/Program.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.

// This application uses the Azure IoT Hub service SDK for .NET
// For samples see: https://github.com/Azure/azure-iot-sdk-csharp/tree/master/iothub/service

using System;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.Azure.Devices;

namespace InvokeDeviceMethod
{
/// <summary>
/// This sample illustrates the very basics of a service app invoking a method on a device.
/// </summary>
internal class Program
{
private static ServiceClient s_serviceClient;

// Connection string for your IoT Hub
// az iot hub show-connection-string --hub-name {your iot hub name} --policy-name service
private static string s_connectionString = "{Your service connection string here}";

private static async Task Main(string[] args)
{
Console.WriteLine("IoT Hub Quickstarts #2 - InvokeDeviceMethod application.");

// This sample accepts the service connection string as a parameter, if present
ValidateConnectionString(args);

// Create a ServiceClient to communicate with service-facing endpoint on your hub.
s_serviceClient = ServiceClient.CreateFromConnectionString(s_connectionString);

await InvokeMethodAsync();

s_serviceClient.Dispose();

Console.WriteLine("\nPress Enter to exit.");
Console.ReadLine();
}

// Invoke the direct method on the device, passing the payload
private static async Task InvokeMethodAsync()
{
var methodInvocation = new CloudToDeviceMethod("SetTelemetryInterval")
{
ResponseTimeout = TimeSpan.FromSeconds(30),
};
methodInvocation.SetPayloadJson("10");

// Invoke the direct method asynchronously and get the response from the simulated device.
var response = await s_serviceClient.InvokeDeviceMethodAsync("MyDotnetDevice", methodInvocation);

Console.WriteLine($"\nResponse status: {response.Status}, payload:\n\t{response.GetPayloadAsJson()}");
}

private static void ValidateConnectionString(string[] args)
{
if (args.Any())
{
try
{
var cs = IotHubConnectionStringBuilder.Create(args[0]);
s_connectionString = cs.ToString();
}
catch (Exception)
{
Console.WriteLine($"Error: Unrecognizable parameter '{args[0]}' as connection string.");
Environment.Exit(1);
}
}
else
{
try
{
_ = IotHubConnectionStringBuilder.Create(s_connectionString);
}
catch (Exception)
{
Console.WriteLine("This sample needs a device connection string to run. Program.cs can be edited to specify it, or it can be included on the command-line as the only parameter.");
Environment.Exit(1);
}
}
}
}
}
8 changes: 4 additions & 4 deletions iot-hub/Quickstarts/Quickstarts.sln
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,13 @@ Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 16
VisualStudioVersion = 16.0.30717.126
MinimumVisualStudioVersion = 15.0.26124.0
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "back-end-application", "back-end-application\back-end-application.csproj", "{F029ED62-3E01-429A-8E32-4862990A35E2}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "InvokeDeviceMethod", "InvokeDeviceMethod\InvokeDeviceMethod.csproj", "{F029ED62-3E01-429A-8E32-4862990A35E2}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "read-d2c-messages", "read-d2c-messages\read-d2c-messages.csproj", "{7701514F-DA48-4344-82FE-4C4A1E7577F9}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ReadD2cMessages", "ReadD2cMessages\ReadD2cMessages.csproj", "{7701514F-DA48-4344-82FE-4C4A1E7577F9}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SimulatedDevice", "simulated-device\SimulatedDevice.csproj", "{C22BD1F5-D8A7-452A-96C4-FF0C0553EBF3}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SimulatedDevice", "SimulatedDevice\SimulatedDevice.csproj", "{C22BD1F5-D8A7-452A-96C4-FF0C0553EBF3}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SimulatedDeviceWithCommand", "simulated-device-2\SimulatedDeviceWithCommand.csproj", "{3B033BD3-38B4-4B92-8871-2787DD7C86CC}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SimulatedDeviceWithCommand", "SimulatedDeviceWithCommand\SimulatedDeviceWithCommand.csproj", "{3B033BD3-38B4-4B92-8871-2787DD7C86CC}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Expand Down
44 changes: 44 additions & 0 deletions iot-hub/Quickstarts/ReadD2cMessages/Parameters.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.

using CommandLine;

namespace ReadD2cMessages
{
/// <summary>
/// Parameters for the application
/// </summary>
internal class Parameters
{
internal const string IotHubSharedAccessKeyName = "service";

[Option(
'e',
"EventHubCompatibleEndpoint",
HelpText = "The event hub-compatible endpoint from your IoT Hub instance. Use `az iot hub show --query properties.eventHubEndpoints.events.endpoint --name {your IoT Hub name}` to fetch via the Azure CLI.")]
public string EventHubCompatibleEndpoint { get; set; }

[Option(
'n',
"EventHubName",
HelpText = "The event hub-compatible name of your IoT Hub instance. Use `az iot hub show --query properties.eventHubEndpoints.events.path --name {your IoT Hub name}` to fetch via the Azure CLI.")]
public string EventHubName { get; set; }

[Option(
's',
"SharedAccessKey",
HelpText = "A primary or shared access key from your IoT Hub instance, with the 'service' permission. Use `az iot hub policy show --name service --query primaryKey --hub-name {your IoT Hub name}` to fetch via the Azure CLI.")]
public string SharedAccessKey { get; set; }

[Option(
'c',
"EventHubConnectionString",
HelpText = "The connection string to the event hub-compatible endpoint. Use the Azure portal to get this parameter. If this value is provided, all the others are not necessary.")]
public string EventHubConnectionString { get; set; }

internal string GetEventHubConnectionString()
{
return EventHubConnectionString ?? $"Endpoint={EventHubCompatibleEndpoint};SharedAccessKeyName={IotHubSharedAccessKeyName};SharedAccessKey={SharedAccessKey}";
}
}
}
120 changes: 120 additions & 0 deletions iot-hub/Quickstarts/ReadD2cMessages/Program.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.

// This application uses the Azure Event Hubs Client for .NET
// For samples see: https://github.com/Azure/azure-sdk-for-net/blob/master/sdk/eventhub/Azure.Messaging.EventHubs/samples/README.md
// For documentation see: https://docs.microsoft.com/azure/event-hubs/

using Azure.Messaging.EventHubs.Consumer;
using CommandLine;
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace ReadD2cMessages
{
/// <summary>
/// A sample to illustrate reading Device-to-Cloud messages from a service app.
/// </summary>
internal class Program
{
private static Parameters _parameters;

public static async Task Main(string[] args)
{
// Parse application parameters
ParserResult<Parameters> result = Parser.Default.ParseArguments<Parameters>(args)
.WithParsed(parsedParams =>
{
_parameters = parsedParams;
})
.WithNotParsed(errors =>
{
Environment.Exit(1);
});

// Either the connection string must be supplied, or the set of endpoint, name, and shared access key must be.
if (string.IsNullOrWhiteSpace(_parameters.EventHubConnectionString)
&& (string.IsNullOrWhiteSpace(_parameters.EventHubCompatibleEndpoint)
|| string.IsNullOrWhiteSpace(_parameters.EventHubName)
|| string.IsNullOrWhiteSpace(_parameters.SharedAccessKey)))
{
Console.WriteLine(CommandLine.Text.HelpText.AutoBuild(result, null, null));
Environment.Exit(1);
}

Console.WriteLine("IoT Hub Quickstarts - Read device to cloud messages. Ctrl-C to exit.\n");

// Set up a way for the user to gracefully shutdown
using var cts = new CancellationTokenSource();
Console.CancelKeyPress += (sender, eventArgs) =>
{
eventArgs.Cancel = true;
cts.Cancel();
Console.WriteLine("Exiting...");
};

// Run the sample
await ReceiveMessagesFromDeviceAsync(cts.Token);

Console.WriteLine("Cloud message reader finished.");
}

// Asynchronously create a PartitionReceiver for a partition and then start
// reading any messages sent from the simulated client.
private static async Task ReceiveMessagesFromDeviceAsync(CancellationToken ct)
{
string connectionString = _parameters.GetEventHubConnectionString();

// Create the consumer using the default consumer group using a direct connection to the service.
// Information on using the client with a proxy can be found in the README for this quick start, here:
// https://github.com/Azure-Samples/azure-iot-samples-csharp/tree/master/iot-hub/Quickstarts/ReadD2cMessages/README.md#websocket-and-proxy-support
await using var consumer = new EventHubConsumerClient(
EventHubConsumerClient.DefaultConsumerGroupName,
connectionString,
_parameters.EventHubName);

Console.WriteLine("Listening for messages on all partitions.");

try
{
// Begin reading events for all partitions, starting with the first event in each partition and waiting indefinitely for
// events to become available. Reading can be canceled by breaking out of the loop when an event is processed or by
// signaling the cancellation token.
//
// The "ReadEventsAsync" method on the consumer is a good starting point for consuming events for prototypes
// and samples. For real-world production scenarios, it is strongly recommended that you consider using the
// "EventProcessorClient" from the "Azure.Messaging.EventHubs.Processor" package.
//
// More information on the "EventProcessorClient" and its benefits can be found here:
// https://github.com/Azure/azure-sdk-for-net/blob/master/sdk/eventhub/Azure.Messaging.EventHubs.Processor/README.md
await foreach (PartitionEvent partitionEvent in consumer.ReadEventsAsync(ct))
{
Console.WriteLine($"\nMessage received on partition {partitionEvent.Partition.PartitionId}:");

string data = Encoding.UTF8.GetString(partitionEvent.Data.Body.ToArray());
Console.WriteLine($"\tMessage body: {data}");

Console.WriteLine("\tApplication properties (set by device):");
foreach (KeyValuePair<string, object> prop in partitionEvent.Data.Properties)
{
Console.WriteLine($"\t\t{prop.Key}: {prop.Value}");
}

Console.WriteLine("\tSystem properties (set by IoT Hub):");
foreach (KeyValuePair<string, object> prop in partitionEvent.Data.SystemProperties)
{
Console.WriteLine($"\t\t{prop.Key}: {prop.Value}");
}
}
}
catch (TaskCanceledException)
{
// This is expected when the token is signaled; it should not be considered an
// error in this scenario.
}
}
}
}
Original file line number Diff line number Diff line change
@@ -1,17 +1,16 @@
# Read device-to-cloud messages

This sample demonstrates how to use the Azure Event Hubs client library for .NET to read messages sent from a device by using the built-in Event Hub that exists by default for every IoT Hub instance.
This sample demonstrates how to use the Azure Event Hubs client library for .NET to read messages sent from a device by using the built-in Event Hub that exists by default for every IoT Hub instance.

## Prerequisites

The .NET Core SDK 3.0.0 or greater is recommended. You can download the .NET Core SDK for multiple platforms from [.NET](https://www.microsoft.com/net/download/all). You can verify the current version of C# on your development machine using 'dotnet --version'.
The .NET SDK 3.1 is recommended. You can download the .NET Core SDK for multiple platforms from [.NET](https://www.microsoft.com/net/download/all). You can verify the current version of C# on your development machine using 'dotnet --version'.

This sample can also be compiled using the NET Core SDK 2.1 SDK if the language version of project is changed to `preview`.
> Note: the Event Hubs client 5.2 does not work with .NET 5.0.
## Obtain the Event Hubs-compatible connection string
## Obtain the Event Hub-compatible connection string

You can get the Event Hubs-compatible connection string to your IotHub instance via the Azure portal or
by using the Azure CLI.
You can get the Event Hub-compatible connection string to your Iot Hub instance via the Azure portal or by using the Azure CLI.

If using the Azure portal, see [Built in endpoints for IotHub](https://docs.microsoft.com/en-us/azure/iot-hub/iot-hub-devguide-messages-read-builtin#read-from-the-built-in-endpoint) to get the Event Hubs-compatible connection string and assign it to the variable `connectionString` in the sample. You can skip the Azure CLI instructions in the sample after this.

Expand Down Expand Up @@ -42,7 +41,7 @@ IWebProxy proxy = new WebProxy("<< URI TO PROXY >>", true);
options.ConnectionOptions.Proxy = proxy;
```

Once you have your options, you'll need to pass them to the client constructor. Each constructor accepts a set of options as the last parameter, such as:
Once you have your options, you'll need to pass them to the client constructor. Each constructor accepts a set of options as the last parameter, such as:

```csharp
string consumerGroup = EventHubConsumerClient.DefaultConsumerGroupName;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,14 @@

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp2.1</TargetFramework>
<TargetFramework>netcoreapp3.1</TargetFramework>
<LangVersion>latest</LangVersion>
<Description></Description>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Azure.Messaging.EventHubs" Version="5.*" />
<PackageReference Include="Azure.Messaging.EventHubs" Version="5.2" />
<PackageReference Include="CommandLineParser" Version="2.8.0" />
</ItemGroup>

</Project>
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ private static async Task Main(string[] args)
{
eventArgs.Cancel = true;
cts.Cancel();
Console.WriteLine("Device simulator exit requested...");
Console.WriteLine("Exiting...");
};

// Run the telemetry loop
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ private static async Task Main(string[] args)
{
eventArgs.Cancel = true;
cts.Cancel();
Console.WriteLine("Device simulator exit requested...");
Console.WriteLine("Exiting...");
};

// Run the telemetry loop
Expand Down
44 changes: 0 additions & 44 deletions iot-hub/Quickstarts/back-end-application/BackEndApplication.cs

This file was deleted.

Loading

0 comments on commit 042befa

Please sign in to comment.