从 Raspberry 向 Azure Iot Hub 发送消息

Sending message to Azure Iot Hub from Raspberry

我需要从我的 Raspberry 中安装的通用应用程序向 Azure Iot Hub (https://azure.microsoft.com/it-it/services/iot-hub/) 发送消息。我必须使用 HTTP 协议,因为 Raspberry 不支持 AMQP。 我使用以下代码:

public sealed partial class MainPage : Page
{
    private DispatcherTimer _timer = null;
    private DeviceClient _deviceClient = null;
    private const string _deviceConnectionString = "<myConnectionString>";

    public MainPage()
    {
        InitializeComponent();

        _deviceClient = DeviceClient.CreateFromConnectionString(_deviceConnectionString, TransportType.Http1);

        _timer = new DispatcherTimer();
        _timer.Interval = TimeSpan.FromSeconds(5);
        _timer.Tick += _timer_Tick;
        _timer.Start();
    }

    private async void _timer_Tick(object sender, object e)
    {
        string msg = "{deviceId: 'myFirstDevice', timestamp: " + DateTime.Now.Ticks + " }";

        Message eventMessage = new Message(Encoding.UTF8.GetBytes(msg));
        await _deviceClient.SendEventAsync(eventMessage);
    }
}

SendEventAsync 给我:

Exception thrown: 'Microsoft.Azure.Devices.Client.Exceptions.IotHubCommunicationException' in mscorlib.ni.dll

Message: {"An error occurred while sending the request."}

我已经将 Microsoft.AspNet.WebApi.Client 包含在我的项目中,如此处记录:https://github.com/Azure/azure-iot-sdks/issues/65 没有结果。

"dependencies": {
    "Microsoft.AspNet.WebApi.Client": "5.2.3",
    "Microsoft.Azure.Devices.Client": "1.0.0-preview-007",
    "Microsoft.NETCore.UniversalWindowsPlatform": "5.0.0"
 },
"frameworks": {
    "uap10.0": {}
}

如果我在控制台应用程序中尝试相同的代码,它会按预期工作。

@danvy 是对的,你需要生成一个 SAS 令牌,这里是一个签名生成器 https://github.com/sandrinodimattia/RedDog/releases

可能有多种发送事件的方式,您使用的是 http,请查看此示例

// Generate a SAS key with the Signature Generator.: 
var sas = "SharedAccessSignature sr=https%3a%2f%2freddogeventhub.servicebus.windows.net%2ftemperature%2fpublishers%2flivingroom%2fmessages&sig=I7n%2bqlIExBRs23V4mcYYfYVYhc6adOlMAeTY9VM9kNg%3d&se=1405562228&skn=SenderDevice";

// Namespace info.
var serviceNamespace = "myeventhub";  
var hubName = "temperature";  
var deviceName = "livingroom";

// Create client.
var httpClient = new HttpClient();  
httpClient.BaseAddress =  
           new Uri(String.Format("https://{0}.servicebus.windows.net/", serviceNamespace));
httpClient.DefaultRequestHeaders  
           .TryAddWithoutValidation("Authorization", sas);

Console.WriteLine("Starting device: {0}", deviceName);

// Keep sending.
while (true)  
{
    var eventData = new
    {
        Temperature = new Random().Next(20, 50)
    };

    var postResult = httpClient.PostAsJsonAsync(
           String.Format("{0}/publishers/{1}/messages", hubName, deviceName), eventData).Result;

    Console.WriteLine("Sent temperature using HttpClient: {0}", 
           eventData.Temperature);
    Console.WriteLine(" > Response: {0}", 
           postResult.StatusCode);
    Console.WriteLine(" > Response Content: {0}", 
           postResult.Content.ReadAsStringAsync().Result);

    Thread.Sleep(new Random().Next(1000, 5000));
}

查看这篇文章了解更多详情http://fabriccontroller.net/iot-with-azure-service-bus-event-hubs-authenticating-and-sending-from-any-type-of-device-net-and-js-samples/

尝试使用本教程为您的设备 (_deviceConnectionString) 设置连接字符串

https://github.com/Azure/azure-iot-sdks/blob/master/tools/DeviceExplorer/doc/how_to_use_device_explorer.md

您可以使用直接从 IoT 中心或从 IoT Suite 向导创建的仪表板获得的信息手动完成。看起来像这样

_deviceConnectionString = "HostName=YourIoTHubName.azure-devices.net;DeviceId=YourDeviceId;SharedAccessKey=YourDeviceSharedAccessKey";

您是否使用 CreateDeviceIdentity 工具正确生成了 DeviceId 和设备密钥? 这是指南:https://blogs.windows.com/buildingapps/2015/12/09/windows-iot-core-and-azure-iot-hub-putting-the-i-in-iot/

经过几个小时的搜索,我发现了一个硬件问题。我的 Raspberry 试图使用未配置的 Wi-Fi dongle 发送请求,而所有其他请求都使用网络电缆。移除加密狗就可以了。