Sending C2D message to Azure IoT Edge

1k views Asked by At

I know C2D is not supported in Azure IoT Edge and an option is to use Direct Method.

Is that can I use Module Client code and send message to a Module ?

I have a ModuleA which has output1 and ModuleB has a Handler input1. I have a route as below

"ModuleAToModuleB": "FROM /messages/modules/ModuleA/outputs/output1 INTO BrokeredEndpoint(\"/modules/ModuleB/inputs/input1\")",

And I use the below code from a console app and send message to a specific module based on the connection string of the specific Module (ModuleA connection string)

string dataString = JsonConvert.SerializeObject(jData);
byte[] dataBytes = Encoding.UTF8.GetBytes(dataString);
var pipeMessage = new Message(dataBytes);
var moduleClient = ModuleClient.CreateFromConnectionString("HostName=xxx.azure-devices.net;DeviceId=xxx-01;ModuleId=ModuleA;SharedAccessKey=XXXXXXX", TransportType.Mqtt);
await moduleClient.SendEventAsync("output1", pipeMessage);

Will this code work, Will it send the Message from ModuleA to ModuleB ?

2

There are 2 answers

0
Matthijs van der Veer On BEST ANSWER

If you want to send anything frfom your laptop/pc in a console app to your IoT Edge device, you will need to use direct methods, like you mentioned in your question. To do that, you can use the Service SDK and use the following method:

InvokeDeviceMethodAsync(string deviceId, string moduleId, CloudToDeviceMethod cloudToDeviceMethod);

In your sample, you suggested using the ModuleClient to send a message to your module. This will not work, ModuleClient is designed to be used only in the Azure IoT Edge runtime, and the method you are using (ModuleClient.CreateFromConnectionString), is one that the runtime will use to set up a connection, using the environment variables available on the device.

With the Service SDK, you can send a direct method to your Module A, and nothing is stopping you to forward the payload of that method into Module B. You already have set up your route correctly.

0
iAviator On

You need to call function like InvokeMethodAsync which is direct method from moduleA to moduelB can be called. In the example you showed it seems you are calling sendEventAsync which might not work. Example is here in C#.

Also please go through this link which also suggests another method for module to module communication.

In addition to using direct methods, it's also possible for two modules to communicate directly with each other, bypassing the Edge Hub. The runtime, via Docker's networking capabilities, manages the DNS entries for each module (container). This allows one module to resolve the IP address of another module by its name.

For an example of this in action, you can follow the SQL tutorial here: https://learn.microsoft.com/en-us/azure/iot-edge/tutorial-store-data-sql-server. This tutorial uses a module to read data out of the Edge Hub and write it into another module hosting SQLServer using the SQLServer client SDK. This interaction with SQLServer does not use the Edge Hub for communicating