diff --git a/DeviceConnectionAndReliabilityReadme.md b/DeviceConnectionAndReliabilityReadme.md new file mode 100644 index 0000000000..b438f6589d --- /dev/null +++ b/DeviceConnectionAndReliabilityReadme.md @@ -0,0 +1,62 @@ +# Azure IoT Device Client C# SDK + +## Device connection and messaging reliability + +### Overview + +In this document you will find information about + +- The connection authentication and renewal methods. +- The reconnection logic and retry policies. +- The timeout controls. + +### Connection authentication + +Authentication can be done using either + +- [SAS tokens](https://docs.microsoft.com/en-us/azure/iot-hub/iot-hub-devguide-security#security-tokens) - [Sample usage](https://github.com/Azure-Samples/azure-iot-samples-csharp/blob/master/iot-hub/Samples/device/TwinSample/Program.cs#L37) +- [x509 certificates](https://docs.microsoft.com/en-us/azure/iot-hub/iot-hub-devguide-security#supported-x509-certificates) - [Sample usage](https://github.com/Azure-Samples/azure-iot-samples-csharp/blob/master/iot-hub/Samples/device/X509DeviceCertWithChainSample/Program.cs#L43) +- [Device Provisioning Service](https://docs.microsoft.com/en-us/azure/iot-dps) - [Sample usage](https://github.com/Azure-Samples/azure-iot-samples-csharp/blob/master/iot-hub/Samples/device/PnpDeviceSamples/Thermostat/Program.cs#L90) + +When using SAS tokens, authentication can be done by: + +- Providing the shared access key and letting the SDK create the SAS tokens by using one of the [CreateFromConnectionString](https://github.com/Azure/azure-iot-sdk-csharp/blob/master/iothub/device/src/DeviceClient.cs#L121) options on the DeviceClient or an authenticationMethod other than DeviceAuthenticationWithTokenRefresh. + + If you choose this option, the SDK will create the SAS tokens and renew them before expiry. The default values for time to live and renewal buffer can be changed using the [ClientOptions](https://github.com/Azure/azure-iot-sdk-csharp/blob/master/iothub/device/src/ClientOptions.cs) properties. + - SasTokenTimeToLive : The suggested time to live value for tokens generated for SAS authenticated clients. Default value is 60 minutes. + - SasTokenRenewalBuffer : The time buffer before expiry when the token should be renewed, expressed as a percentage of the time to live. Acceptable values lie between 0 and 100.Default value is 15%. + + Note: If the shared access policy name is not specified in the connection string, it will be set to - `/devices/` +> +- Providing only the shared access signature + + If you only provide the shared access signature and authenticationMethod is not of type AuthenticationWithTokenRefresh, there will be no automatic renewal. +> +- Providing your own SAS token using [DeviceAuthenticationWithTokenRefresh](https://github.com/Azure/azure-iot-sdk-csharp/blob/master/iothub/device/src/DeviceAuthenticationWithTokenRefresh.cs) authenticationMethod + + If you choose to use your own implementation to generate tokens, you can provide the time to live and time buffer before exipry through the DeviceAuthenticationWithTokenRefresh constructor. The ClientOptions apply only to other authentication methods. + +When using x509 certificates, [DeviceAuthenticationWithX509Certificate](https://github.com/Azure/azure-iot-sdk-csharp/blob/master/iothub/device/src/DeviceAuthenticationWithX509Certificate.cs) authenticationMethod can be used. The client authentication will be valid until the certificate is valid. Any renewal will have to be done manually and the client needs to be recreated. + +### Connection retry logic + +For both AMQP and MQTT, the SDK will try to re-connect everytime there is any disruption. The default retry policy does not have a time limit and will follow exponential back-off. + +For more details, see [here](https://github.com/Azure/azure-iot-sdk-csharp/blob/master/iothub/device/devdoc/retrypolicy.md). + +HTTP is a stateless protocol and will work whenever there is network connectivity. + +### Timeout controls + +There are different timeout values that can be configured for the DeviceClient based on the protocol. These values are configuarable through the following transport settings that are passed while creating the client. There will be no changes to any of the settings once the DeviceClient is created. The client needs to be recreated with new settings to make changes. + +AMQP transport settings - [AmqpTransportSettings](https://github.com/Azure/azure-iot-sdk-csharp/blob/master/iothub/device/src/AmqpTransportSettings.cs) + +* IdleTimeout - The interval, in seconds, that the client establishes with the service, for sending keep alive pings. The default value is 2 minutes. +* OperationTimeout - The time to wait for any operation to complete. The default is 1 minute. +* OpenTimeout - This value is not used (TODO: Confirm and update) + +MQTT transport settings - [MqttTransportSettings](https://github.com/Azure/azure-iot-sdk-csharp/blob/master/iothub/device/src/Transport/Mqtt/MqttTransportSettings.cs) +* ConnectArrivalTimeout - The time to wait for receiving an acknowledgment for a CONNECT packet. The default is 1 minute. +* KeepAliveInSeconds - The interval, in seconds, that the client establishes with the service, for sending keep alive pings. The default value is 5 minutes. +* DeviceReceiveAckTimeout - The time a device will wait, for an acknowledgment from service. The default is 5 minutes. \ No newline at end of file diff --git a/iothub/device/src/AmqpTransportSettings.cs b/iothub/device/src/AmqpTransportSettings.cs index 272844f6e8..811f6de228 100644 --- a/iothub/device/src/AmqpTransportSettings.cs +++ b/iothub/device/src/AmqpTransportSettings.cs @@ -115,12 +115,18 @@ public AmqpTransportSettings(TransportType transportType, uint prefetchCount, Am /// /// Specify client-side heartbeat interval. + /// The interval, in seconds, that the client establishes with the service, for sending keep alive pings. /// The default value is 2 minutes. /// + /// + /// The client will consider the connection as disconnected if the keep alive ping fails. + /// Setting a very low idle timeout value can cause aggressive reconnects, and might not give the + /// client enough time to establish a connection before disconnecting and reconnecting. + /// public TimeSpan IdleTimeout { get; set; } /// - /// The operation timeout + /// The time to wait for any operation to complete. The default is 1 minute. /// public TimeSpan OperationTimeout { @@ -129,7 +135,7 @@ public TimeSpan OperationTimeout } /// - /// The open timeout + /// The open timeout. The default is 1 minute. /// public TimeSpan OpenTimeout { @@ -138,7 +144,7 @@ public TimeSpan OpenTimeout } /// - /// The pre-fetch count + /// The number of messages that the message receiver can simultaneously request. The default is 50. /// public uint PrefetchCount { get; set; } @@ -172,7 +178,7 @@ public TransportType GetTransportType() } /// - /// Returns the default current receive timeout + /// The time to wait for a receive operation. The default value is 1 minute. /// public TimeSpan DefaultReceiveTimeout => DefaultOperationTimeout; diff --git a/iothub/device/src/Http1TransportSettings.cs b/iothub/device/src/Http1TransportSettings.cs index b16efc486d..d8d638d30e 100644 --- a/iothub/device/src/Http1TransportSettings.cs +++ b/iothub/device/src/Http1TransportSettings.cs @@ -13,7 +13,7 @@ namespace Microsoft.Azure.Devices.Client /// public sealed class Http1TransportSettings : ITransportSettings { - private static readonly TimeSpan s_defaultOperationTimeout = TimeSpan.FromSeconds(60); + private static readonly TimeSpan s_defaultOperationTimeout = TimeSpan.FromMinutes(1); /// /// Initializes a new instance of the class. @@ -40,6 +40,9 @@ public TransportType GetTransportType() /// /// The time to wait for a receive operation. The default value is 1 minute. /// + /// + /// This property is currently unused. + /// public TimeSpan DefaultReceiveTimeout => s_defaultOperationTimeout; /// diff --git a/iothub/device/src/ITransportSettings.cs b/iothub/device/src/ITransportSettings.cs index 045e932eb6..05a19f4b66 100644 --- a/iothub/device/src/ITransportSettings.cs +++ b/iothub/device/src/ITransportSettings.cs @@ -17,7 +17,7 @@ public interface ITransportSettings TransportType GetTransportType(); /// - /// The default receive timeout. + /// The time to wait for a receive operation. The default value is 1 minute. /// TimeSpan DefaultReceiveTimeout { get; } } diff --git a/iothub/device/src/Transport/Mqtt/MqttTransportSettings.cs b/iothub/device/src/Transport/Mqtt/MqttTransportSettings.cs index 99fe30cbd9..ee5d621f1b 100644 --- a/iothub/device/src/Transport/Mqtt/MqttTransportSettings.cs +++ b/iothub/device/src/Transport/Mqtt/MqttTransportSettings.cs @@ -188,6 +188,8 @@ public bool CertificateRevocationCheck /// /// The client will send a ping request 4 times per keep-alive duration set. /// It will wait for 30 seconds for the ping response, else mark the connection as disconnected. + /// Setting a very low keep alive value can cause aggressive reconnects, and might not give the + /// client enough time to establish a connection before disconnecting and reconnecting. /// public int KeepAliveInSeconds { get; set; } diff --git a/readme.md b/readme.md index d0ca4c0a96..97f50a8c89 100644 --- a/readme.md +++ b/readme.md @@ -147,6 +147,7 @@ This repository contains [provisioning service client SDK](./provisioning/servic - [Set up your development environment](./doc/devbox_setup.md) to prepare your development environment as well as how to run the samples on Linux, Windows or other platforms. - [API reference documentation for .NET](https://docs.microsoft.com/dotnet/api/overview/azure/devices?view=azure-dotnet) - [Get Started with IoT Hub using .NET](https://docs.microsoft.com/azure/iot-hub/iot-hub-csharp-csharp-getstarted) +- [Device connection and messaging reliability](https://github.com/Azure/azure-iot-sdk-csharp/blob/master/DeviceConnectionAndReliabilityReadme.md) > Device Explorer is no longer supported. A replacement tool can be found [here](https://github.com/Azure/azure-iot-explorer).