Search code examples
azuresocketsdeviceazure-iot-hub

How to solve Unhandle Exception:System.Net Socket.SocketException in azure iot readmessage device?


Hi i have the following code, that reads the message to the device. I have azure portal running. But i get the following exception when running on a command prompt;

// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.

    using System;
    using Microsoft.Azure.EventHubs;
    using System.Threading.Tasks;
    using System.Threading;
    using System.Text;
    using System.Collections.Generic;

        namespace read_d2c_messages
        {
            class ReadDeviceToCloudMessages
            {
                // Event Hub-compatible endpoint
                // az iot hub show --query properties.eventHubEndpoints.events.endpoint --name {your IoT Hub name}
                private readonly static string s_eventHubsCompatibleEndpoint ="sb://iothub-ns-mydeviceco......";

                // Event Hub-compatible name
                // az iot hub show --query properties.eventHubEndpoints.events.path --name {your IoT Hub name}
                private readonly static string s_eventHubsCompatiblePath = "mydeviceconnection";

                // az iot hub policy show --name service --query primaryKey --hub-name {your IoT Hub name}
                private readonly static string s_iotHubSasKey = "";
                private readonly static string s_iotHubSasKeyName = "service";
                private static EventHubClient s_eventHubClient;

                // Asynchronously create a PartitionReceiver for a partition and then start 
                // reading any messages sent from the simulated client.
                private static async Task ReceiveMessagesFromDeviceAsync(string partition, CancellationToken ct)
                {
                    // Create the receiver using the default consumer group.
                    // For the purposes of this sample, read only messages sent since 
                    // the time the receiver is created. Typically, you don't want to skip any messages.
                    var eventHubReceiver = s_eventHubClient.CreateReceiver("$Default", partition, EventPosition.FromEnqueuedTime(DateTime.Now));
                    Console.WriteLine("Create receiver on partition: " + partition);
                    while (true)
                    {
                        if (ct.IsCancellationRequested) break;
                        Console.WriteLine("Listening for messages on: " + partition);
                        // Check for EventData - this methods times out if there is nothing to retrieve.
                        var events = await eventHubReceiver.ReceiveAsync(100);

                        // If there is data in the batch, process it.
                        if (events == null) continue;

                        foreach(EventData eventData in events)
                        { 
                          string data = Encoding.UTF8.GetString(eventData.Body.Array);
                          Console.WriteLine("Message received on partition {0}:", partition);
                          Console.WriteLine("  {0}:", data);
                          Console.WriteLine("Application properties (set by device):");
                          foreach (var prop in eventData.Properties)
                          {
                            Console.WriteLine("  {0}: {1}", prop.Key, prop.Value);
                          }
                          Console.WriteLine("System properties (set by IoT Hub):");
                          foreach (var prop in eventData.SystemProperties)
                          {
                            Console.WriteLine("  {0}: {1}", prop.Key, prop.Value);
                          }
                        }
                    }
                }

                private static async Task Main(string[] args)
                {
                    Console.WriteLine("IoT Hub Quickstarts - Read device to cloud messages. Ctrl-C to exit.\n");

                    // Create an EventHubClient instance to connect to the
                    // IoT Hub Event Hubs-compatible endpoint.
                    var connectionString = new EventHubsConnectionStringBuilder(new Uri(s_eventHubsCompatibleEndpoint), s_eventHubsCompatiblePath, s_iotHubSasKeyName, s_iotHubSasKey);
                    s_eventHubClient = EventHubClient.CreateFromConnectionString(connectionString.ToString());

                    // Create a PartitionReciever for each partition on the hub.
                    var runtimeInfo = await s_eventHubClient.GetRuntimeInformationAsync();
                    var d2cPartitions = runtimeInfo.PartitionIds;

                    CancellationTokenSource cts = new CancellationTokenSource();

                    Console.CancelKeyPress += (s, e) =>
                    {
                        e.Cancel = true;
                        cts.Cancel();
                        Console.WriteLine("Exiting...");
                    };

                    var tasks = new List<Task>();
                    foreach (string partition in d2cPartitions)
                    {
                        tasks.Add(ReceiveMessagesFromDeviceAsync(partition, cts.Token));
                    }

                    // Wait for all the PartitionReceivers to finsih.
                    Task.WaitAll(tasks.ToArray());
                }
            }
        }

On my command prompt, the exception is System.Net.Sockets.SocketException:A connection attempt failed because the connected party did not properly respond after a period of time, or established failed because host has failed to respond at Microsoft.Azure.EventHub.Amqp.AmqpHubClient.CreateConnectionAsync(TimeSpan, Timeout); What kind of error is this? Is had to do with firewall connectivity issue on my connection string not to receive message? Or hence i am using Free Trail cant be able to create Service-Bus-Messsage on my EndPoint?


Solution

  • I think the way you construct your connection string is not quite correct. When you copy the connection string from your IoT Hub in the full format, this should already work:

    s_eventHubClient = EventHubClient.CreateFromConnectionString("Endpoint=sb://iothub-xxxxxx-1180347-e18a7c8824.servicebus.windows.net/;SharedAccessKeyName=iothubowner;SharedAccessKey=qya62bOiN0********gIyEQ=;EntityPath=myiothubname");