Xamarin.forms 通过IoTHub/Xamarin App/ESP8266进行双向通信

Xamarin.forms 通过IoTHub/Xamarin App/ESP8266进行双向通信,xamarin.forms,azure-iot-hub,Xamarin.forms,Azure Iot Hub,正在开发一款新产品,该产品将使用ESP8266、Xamarin应用程序和Azure IoTHub为客户设备实现双向通信 我们已经在应用程序和ESP上实现了C2D(云2设备)和D2C(设备2云)通信正常工作,但我们没有找到任何关于设置IoTHub以解释传入遥测消息、处理其各自的“收件人:”字段并将其放回C2D主题的信息,这应该允许我们的目标设备接收它 我们的尝试: 逻辑应用程序。我们能够在传入消息时触发队列,但不确定HTTP请求要做什么才能将其转发回C2D事件中心 我们已经成功地将每条消息转发到队

正在开发一款新产品,该产品将使用ESP8266、Xamarin应用程序和Azure IoTHub为客户设备实现双向通信

我们已经在应用程序和ESP上实现了C2D(云2设备)和D2C(设备2云)通信正常工作,但我们没有找到任何关于设置IoTHub以解释传入遥测消息、处理其各自的“收件人:”字段并将其放回C2D主题的信息,这应该允许我们的目标设备接收它

我们的尝试:

  • 逻辑应用程序。我们能够在传入消息时触发队列,但不确定HTTP请求要做什么才能将其转发回C2D事件中心
  • 我们已经成功地将每条消息转发到队列中,但Xamarin的PCL库无法连接到Azure服务总线队列(bummer)
  • 我找到了一位在微软为车库门开启器开发直接设备对设备通信的实习生的参考资料,但她使用的库仅适用于UWP应用程序,这并不十分方便,因为我们真的想针对iOS、Android和UWP(首先选择Xamarin的原因)


    是否有人能够使用Azure门户触发C2D条件事件?

    通过与Microsoft Azure团队的一些对话,我们确定webjob与队列路由相结合是我们的最佳解决方案

    所有消息都被路由到队列,当它们到达队列时,webjob将处理该消息并使用ServiceBus消息传递对象发送该消息,以发送云到设备响应消息

    这是给任何想使用它的人的代码

    只要消息的原始发送者在代理消息中指定“To”属性,它就会被传递到注册表中的该设备。您需要服务总线和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();
        }
    
    private const string queueName=“”;
    私有常量字符串IoTHubConnectionString=“主机名=;SharedAccessKeyName=;SharedAccessKey=”;
    //写入新消息时,将触发/执行此功能
    //在名为的Azure队列上。
    公共静态void ReceiveQueueMessages(
    [ServiceBusTrigger(queueName)]代理消息消息,
    文本编写器(日志)
    {
    if(message.To==null)
    {
    //消息=null
    返回;
    }
    其他的
    {
    //检索消息正文,而不考虑作为流的内容
    Stream=message.GetBody();
    流阅读器;
    if(流!=null)
    读卡器=新的流读卡器(流);
    其他的
    reader=null;
    字符串s;
    消息服务消息;
    if(读卡器!=null)
    {
    s=reader.ReadToEnd();
    serviceMessage=新的Microsoft.Azure.Devices.Message(Encoding.ASCII.GetBytes);
    }
    其他的
    {
    serviceMessage=新的Microsoft.Azure.Devices.Message();
    }
    foreach(message.Properties中的KeyValuePair属性)
    {
    serviceMessage.Properties.Add(property.Key、property.Value.ToString());
    }
    sendtoothub(message.To.ToString(),serviceMessage);
    }
    }
    静态异步void sendtoothub(字符串目标,Microsoft.Azure.Devices.Message)
    {
    //将其写回目标设备
    ServiceClient ServiceClient=ServiceClient.CreateFromConnectionString(IoTubConnectionString);
    var serviceMessage=消息;
    serviceMessage.Ack=deliveryAcknowledge.Full;
    serviceMessage.MessageId=Guid.NewGuid().ToString();
    尝试
    {
    等待serviceClient.SendAsync(目标,serviceMessage);
    }
    抓住
    {
    等待serviceClient.CloseAsync();
    返回;
    }
    等待serviceClient.CloseAsync();
    }
    
    您检查过吗?您尝试过azure功能吗?您可以订阅启用事件集线器的端点触发器,并具有适当的逻辑来过滤和重定向消息,或者使用iot集线器api与设备通信。我将发布我找到的适用于我的解决方案的答案。