在工作中使用ESP8266,Xamarin应用程序和Azure IoTHub处理新产品,以便为客户的设备启用双向通信。
我们已经在应用程序和ESP上正常运行C2D(云2设备)和D2C(设备2云)通信,但是我们没有找到有关设置IoTHub以解释传入的遥测消息的任何信息,处理他们各自的" To:"字段并将它们放回C2D主题,这应该允许我们的目标设备接收它。
我们尝试了什么:
我找到了一个微软实习生的参考资料,开发了一个车库门开启器的直接设备到设备通信,但她使用的库只适用于UWP应用程序,当我们确实这样做时,这并不是很方便。想要定位iOS,Android和UWP(首先选择Xamarin的原因)。
是否有人能够使用Azure门户触发C2D条件事件?
答案 0 :(得分:3)
通过与Microsoft Azure团队的一些对话,我们确定webjob与队列路由相结合是我们的最佳解决方案。
所有消息都路由到队列,当它们到达队列时,webjob处理消息并使用ServiceBus Messaging对象发送消息,以将云发送到设备响应消息。
以下是任何想要使用它的人的代码。
只要邮件的原始发件人指定" To"在代理消息中的属性,它将被传递到注册表中的该设备。您将需要Service Bus和Azure.Messaging NuGet包才能使用它。此代码将复制整个邮件并将整个邮件发送到所需的注册表设备。
private const string queueName = "<queue_name>";
private const string IoTHubConnectionString = "HostName=<your_host>;SharedAccessKeyName=<your_service_user>;SharedAccessKey=<your sas>";
// This function will get triggered/executed when a new message is written
// on an Azure Queue called <queue_name>.
public static void ReceiveQueueMessages(
[ServiceBusTrigger(queueName)] BrokeredMessage message,
TextWriter log)
{
if (message.To == null)
{
//message = null
return;
}
else
{
//Retrieve the message body regardless of the content as a stream
Stream stream = message.GetBody<Stream>();
StreamReader reader;
if (stream != null)
reader = new StreamReader(stream);
else
reader = null;
string s;
Message serviceMessage;
if ( reader != null )
{
s = reader.ReadToEnd();
serviceMessage = new Microsoft.Azure.Devices.Message(Encoding.ASCII.GetBytes(s));
}
else
{
serviceMessage = new Microsoft.Azure.Devices.Message();
}
foreach (KeyValuePair<string, object> property in message.Properties)
{
serviceMessage.Properties.Add(property.Key, property.Value.ToString());
}
SendToIoTHub(message.To.ToString(), serviceMessage);
}
}
static async void SendToIoTHub(string target, Microsoft.Azure.Devices.Message message)
{
// Write it back out to the target device
ServiceClient serviceClient = ServiceClient.CreateFromConnectionString(IoTHubConnectionString);
var serviceMessage = message;
serviceMessage.Ack = DeliveryAcknowledgement.Full;
serviceMessage.MessageId = Guid.NewGuid().ToString();
try
{
await serviceClient.SendAsync(target, serviceMessage);
}
catch
{
await serviceClient.CloseAsync();
return;
}
await serviceClient.CloseAsync();
}