-
Notifications
You must be signed in to change notification settings - Fork 494
/
MqttTransportSettings.cs
261 lines (228 loc) · 11.8 KB
/
MqttTransportSettings.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
using DotNetty.Codecs.Mqtt.Packets;
using Microsoft.Azure.Devices.Client.Extensions;
using Microsoft.Azure.Devices.Shared;
using System;
using System.Net;
using System.Net.Security;
using System.Security.Cryptography.X509Certificates;
namespace Microsoft.Azure.Devices.Client.Transport.Mqtt
{
/// <summary>
/// Settings for MQTT transport
/// </summary>
public class MqttTransportSettings : ITransportSettings
{
private readonly TransportType _transportType;
private const bool DefaultCleanSession = false;
private const bool DefaultDeviceReceiveAckCanTimeout = false;
private const bool DefaultHasWill = false;
private const bool DefaultMaxOutboundRetransmissionEnforced = false;
private const int DefaultKeepAliveInSeconds = 300;
private const int DefaultMaxPendingInboundMessages = 50;
private const QualityOfService DefaultPublishToServerQoS = QualityOfService.AtLeastOnce;
private const QualityOfService DefaultReceivingQoS = QualityOfService.AtLeastOnce;
// The CONNACK timeout has been chosen to be 60 seconds to be in alignment with the service implemented timeout for processing connection requests.
private static readonly TimeSpan s_defaultConnectArrivalTimeout = TimeSpan.FromSeconds(60);
private static readonly TimeSpan s_defaultDeviceReceiveAckTimeout = TimeSpan.FromSeconds(300);
private static readonly TimeSpan s_defaultReceiveTimeout = TimeSpan.FromMinutes(1);
/// <summary>
/// Creates an instance based on the specified type options
/// </summary>
/// <param name="transportType">The transport type, of Mqtt_WebSocket_Only, or Mqtt_Tcp_Only</param>
public MqttTransportSettings(TransportType transportType)
{
_transportType = transportType;
switch (transportType)
{
case TransportType.Mqtt_WebSocket_Only:
Proxy = DefaultWebProxySettings.Instance;
_transportType = transportType;
break;
case TransportType.Mqtt_Tcp_Only:
_transportType = transportType;
break;
case TransportType.Mqtt:
throw new ArgumentOutOfRangeException(nameof(transportType), transportType, "Must specify Mqtt_WebSocket_Only or Mqtt_Tcp_Only");
default:
throw new ArgumentOutOfRangeException(nameof(transportType), transportType, "Unsupported Transport Type {0}".FormatInvariant(transportType));
}
CleanSession = DefaultCleanSession;
ConnectArrivalTimeout = s_defaultConnectArrivalTimeout;
DeviceReceiveAckCanTimeout = DefaultDeviceReceiveAckCanTimeout;
DeviceReceiveAckTimeout = s_defaultDeviceReceiveAckTimeout;
DupPropertyName = "mqtt-dup";
HasWill = DefaultHasWill;
KeepAliveInSeconds = DefaultKeepAliveInSeconds;
MaxOutboundRetransmissionEnforced = DefaultMaxOutboundRetransmissionEnforced;
MaxPendingInboundMessages = DefaultMaxPendingInboundMessages;
PublishToServerQoS = DefaultPublishToServerQoS;
ReceivingQoS = DefaultReceivingQoS;
QoSPropertyName = "mqtt-qos";
RetainPropertyName = "mqtt-retain";
WillMessage = null;
DefaultReceiveTimeout = s_defaultReceiveTimeout;
}
/// <summary>
/// Indicates if certificate revocation check is enabled. The default value is <c>false</c>.
/// </summary>
[System.Diagnostics.CodeAnalysis.SuppressMessage(
"Performance",
"CA1822:Mark members as static",
Justification = "Cannot change public property in public facing classes.")]
public bool CertificateRevocationCheck
{
get => TlsVersions.Instance.CertificateRevocationCheck;
set => TlsVersions.Instance.CertificateRevocationCheck = value;
}
/// <summary>
/// Indicates if a device can timeout while waiting for a acknowledgment from service.
/// The default value is <c>false</c>.
/// </summary>
/// <remarks>
/// This property is currently unused.
/// </remarks>
public bool DeviceReceiveAckCanTimeout { get; set; }
/// <summary>
/// The time a device will wait for an acknowledgment from service.
/// The default is 5 minutes.
/// </summary>
/// <remarks>
/// This property is currently unused.
/// </remarks>
public TimeSpan DeviceReceiveAckTimeout { get; set; }
/// <summary>
/// The QoS to be used when sending packets to service.
/// The default value is <see cref="QualityOfService.AtLeastOnce"/>.
/// </summary>
public QualityOfService PublishToServerQoS { get; set; }
/// <summary>
/// The QoS to be used when subscribing to receive packets from the service.
/// The default value is <see cref="QualityOfService.AtLeastOnce"/>.
/// </summary>
public QualityOfService ReceivingQoS { get; set; }
/// <summary>
/// The property on a message that indicates the publish packet has requested to be retained.
/// </summary>
/// <remarks>
/// This property is currently unused.
/// </remarks>
public string RetainPropertyName { get; set; }
/// <summary>
/// The property on a message that indicates the publish packet is marked as a duplicate.
/// </summary>
/// <remarks>
/// This property is currently unused.
/// </remarks>
public string DupPropertyName { get; set; }
/// <summary>
/// The property name setting the QoS for a packet.
/// </summary>
/// <remarks>
/// This property is currently unused.
/// </remarks>
public string QoSPropertyName { get; set; }
/// <summary>
/// Indicates if max outbound retransmission is enforced.
/// The default value is <c>false</c>.
/// </summary>
/// <remarks>
/// This property is currently unused.
/// </remarks>
public bool MaxOutboundRetransmissionEnforced { get; set; }
/// <summary>
/// The maximum no. of inbound messages that are read from the channel.
/// The default value is 50.
/// </summary>
public int MaxPendingInboundMessages { get; set; }
/// <summary>
/// The time to wait for receiving an acknowledgment for a CONNECT packet.
/// The default is 60 seconds.
/// </summary>
/// <remarks>
/// In the event that IoT hub receives burst traffic, it will implement traffic shaping in order to process the incoming requests.
/// In such cases, during client connection the CONNECT requests can have a delay in being acknowledged and processed by IoT hub.
/// The <c>ConnectArrivalTimeout</c> governs the duration the client will wait for a CONNACK packet before disconnecting and reopening the connection.
/// To know more about IoT hub's throttling limits and traffic shaping feature, see
/// <see href="https://docs.microsoft.com/azure/iot-hub/iot-hub-devguide-quotas-throttling#operation-throttles"/>.
/// </remarks>
public TimeSpan ConnectArrivalTimeout { get; set; }
/// <summary>
/// Flag to specify if a subscription should persist across different sessions. The default value is false.
/// </summary>
/// <remarks>
/// <para>If set to false: the device will receive messages that were sent to it while it was disconnected.</para>
/// <para>If set to true: the device will receive only those messages that were sent to it
/// after it successfully subscribed to the device bound message topic.</para>
/// </remarks>
public bool CleanSession { get; set; }
/// <summary>
/// The interval, in seconds, that the client establishes with the service, for sending protocol-level keep-alive pings.
/// The default is 300 seconds.
/// </summary>
/// <remarks>
/// 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.
/// </remarks>
public int KeepAliveInSeconds { get; set; }
/// <summary>
/// A keep-alive for the transport layer in sending ping/pong control frames when using web sockets.
/// </summary>
/// <remarks>
/// This value is different from the protocol-level keep-alive packets that are sent over the overlaying MQTT transport protocol.
/// </remarks>
/// <seealso href="https://docs.microsoft.com/dotnet/api/system.net.websockets.clientwebsocketoptions.keepaliveinterval"/>
public TimeSpan? WebSocketKeepAlive { get; set; }
/// <summary>
/// Indicates whether the transport has a will message.
/// </summary>
/// <remarks>
/// Setting a will message is a way for clients to notify other subscribed clients about ungraceful disconnects in an appropriate way.
/// In response to the ungraceful disconnect, the service will send the last-will message to the configured telemetry channel.
/// The telemetry channel can be either the default Events endpoint or a custom endpoint defined by IoT hub routing.
/// For more details, refer to https://docs.microsoft.com/azure/iot-hub/iot-hub-mqtt-support#using-the-mqtt-protocol-directly-as-a-device.
/// </remarks>
public bool HasWill { get; set; }
/// <summary>
/// The configured will message that is sent to the telemetry channel on an ungraceful disconnect.
/// </summary>
/// <remarks>
/// The telemetry channel can be either the default Events endpoint or a custom endpoint defined by IoT hub routing.
/// For more details, refer to https://docs.microsoft.com/azure/iot-hub/iot-hub-mqtt-support#using-the-mqtt-protocol-directly-as-a-device.
/// </remarks>
public IWillMessage WillMessage { get; set; }
/// <summary>
/// The time to wait for a receive operation. The default value is 1 minute.
/// </summary>
/// <remarks>
/// This property is currently unused.
/// </remarks>
public TimeSpan DefaultReceiveTimeout { get; set; }
/// <summary>
/// A callback for remote certificate validation.
/// If incorrectly implemented, your device may fail to connect to IoTHub and/or be open to security vulnerabilities.
/// </summary>
public RemoteCertificateValidationCallback RemoteCertificateValidationCallback { get; set; }
/// <summary>
/// The client certificate to be used for authenticating the TLS connection.
/// </summary>
public X509Certificate ClientCertificate { get; set; }
/// <inheritdoc/>
public IWebProxy Proxy { get; set; }
/// <summary>
/// The connection transport type.
/// </summary>
/// <returns></returns>
public TransportType GetTransportType()
{
return _transportType;
}
/// <summary>
/// Used by Edge runtime to specify an authentication chain for Edge-to-Edge connections.
/// </summary>
internal string AuthenticationChain { get; set; }
}
}