private byte Serialize(MqttConnAckPacket packet, MqttPacketWriter packetWriter) { if (ProtocolVersion == MqttProtocolVersion.V310) { packetWriter.Write(0); } else if (ProtocolVersion == MqttProtocolVersion.V311) { byte connectAcknowledgeFlags = 0x0; if (packet.IsSessionPresent) { connectAcknowledgeFlags |= 0x1; } packetWriter.Write(connectAcknowledgeFlags); } else { throw new MqttProtocolViolationException("Protocol version not supported."); } packetWriter.Write((byte)packet.ConnectReturnCode); return(MqttPacketWriter.BuildFixedHeader(MqttControlPacketType.ConnAck)); }
byte EncodeConnAckPacket(MqttConnAckPacket packet, MqttBufferWriter bufferWriter) { bufferWriter.WriteByte(0); // Reserved. bufferWriter.WriteByte((byte)packet.ReturnCode); return(MqttBufferWriter.BuildFixedHeader(MqttControlPacketType.ConnAck)); }
byte EncodeConnAckPacket(MqttConnAckPacket packet) { byte connectAcknowledgeFlags = 0x0; if (packet.IsSessionPresent) { connectAcknowledgeFlags |= 0x1; } _bufferWriter.WriteByte(connectAcknowledgeFlags); _bufferWriter.WriteByte((byte)packet.ReasonCode); _propertiesWriter.WriteSessionExpiryInterval(packet.SessionExpiryInterval); _propertiesWriter.WriteAuthenticationMethod(packet.AuthenticationMethod); _propertiesWriter.WriteAuthenticationData(packet.AuthenticationData); _propertiesWriter.WriteRetainAvailable(packet.RetainAvailable); _propertiesWriter.WriteReceiveMaximum(packet.ReceiveMaximum); _propertiesWriter.WriteMaximumQoS(packet.MaximumQoS); _propertiesWriter.WriteAssignedClientIdentifier(packet.AssignedClientIdentifier); _propertiesWriter.WriteTopicAliasMaximum(packet.TopicAliasMaximum); _propertiesWriter.WriteReasonString(packet.ReasonString); _propertiesWriter.WriteMaximumPacketSize(packet.MaximumPacketSize); _propertiesWriter.WriteWildcardSubscriptionAvailable(packet.WildcardSubscriptionAvailable); _propertiesWriter.WriteSubscriptionIdentifiersAvailable(packet.SubscriptionIdentifiersAvailable); _propertiesWriter.WriteSharedSubscriptionAvailable(packet.SharedSubscriptionAvailable); _propertiesWriter.WriteServerKeepAlive(packet.ServerKeepAlive); _propertiesWriter.WriteResponseInformation(packet.ResponseInformation); _propertiesWriter.WriteServerReference(packet.ServerReference); _propertiesWriter.WriteUserProperties(packet.UserProperties); _propertiesWriter.WriteTo(_bufferWriter); _propertiesWriter.Reset(); return(MqttBufferWriter.BuildFixedHeader(MqttControlPacketType.ConnAck)); }
protected virtual byte EncodeConnAckPacket(MqttConnAckPacket packet, IMqttPacketWriter packetWriter) { packetWriter.Write(0); // Reserved. packetWriter.Write((byte)packet.ReturnCode.Value); return(MqttPacketWriter.BuildFixedHeader(MqttControlPacketType.ConnAck)); }
public MqttConnAckPacket Create(ValidatingConnectionEventArgs validatingConnectionEventArgs) { if (validatingConnectionEventArgs == null) { throw new ArgumentNullException(nameof(validatingConnectionEventArgs)); } var connAckPacket = new MqttConnAckPacket { ReturnCode = MqttConnectReasonCodeConverter.ToConnectReturnCode(validatingConnectionEventArgs.ReasonCode), ReasonCode = validatingConnectionEventArgs.ReasonCode, RetainAvailable = true, SubscriptionIdentifiersAvailable = true, SharedSubscriptionAvailable = false, TopicAliasMaximum = ushort.MaxValue, MaximumQoS = MqttQualityOfServiceLevel.ExactlyOnce, WildcardSubscriptionAvailable = true, AuthenticationMethod = validatingConnectionEventArgs.AuthenticationMethod, AuthenticationData = validatingConnectionEventArgs.ResponseAuthenticationData, AssignedClientIdentifier = validatingConnectionEventArgs.AssignedClientIdentifier, ReasonString = validatingConnectionEventArgs.ReasonString, ServerReference = validatingConnectionEventArgs.ServerReference, UserProperties = validatingConnectionEventArgs.ResponseUserProperties, ResponseInformation = null, MaximumPacketSize = 0, // Unlimited, ReceiveMaximum = 0 // Unlimited }; return(connAckPacket); }
public MqttClientAuthenticateResult CreateClientConnectResult(MqttConnAckPacket connAckPacket) { if (connAckPacket == null) { throw new ArgumentNullException(nameof(connAckPacket)); } return(new MqttClientAuthenticateResult { IsSessionPresent = connAckPacket.IsSessionPresent, ResultCode = (MqttClientConnectResultCode)connAckPacket.ReasonCode.Value, WildcardSubscriptionAvailable = connAckPacket.Properties?.WildcardSubscriptionAvailable, RetainAvailable = connAckPacket.Properties?.RetainAvailable, AssignedClientIdentifier = connAckPacket.Properties?.AssignedClientIdentifier, AuthenticationMethod = connAckPacket.Properties?.AuthenticationMethod, AuthenticationData = connAckPacket.Properties?.AuthenticationData, MaximumPacketSize = connAckPacket.Properties?.MaximumPacketSize, ReasonString = connAckPacket.Properties?.ReasonString, ReceiveMaximum = connAckPacket.Properties?.ReceiveMaximum, MaximumQoS = connAckPacket.Properties?.MaximumQoS ?? MqttQualityOfServiceLevel.ExactlyOnce, ResponseInformation = connAckPacket.Properties?.ResponseInformation, TopicAliasMaximum = connAckPacket.Properties?.TopicAliasMaximum, ServerReference = connAckPacket.Properties?.ServerReference, ServerKeepAlive = connAckPacket.Properties?.ServerKeepAlive, SessionExpiryInterval = connAckPacket.Properties?.SessionExpiryInterval, SubscriptionIdentifiersAvailable = connAckPacket.Properties?.SubscriptionIdentifiersAvailable, SharedSubscriptionAvailable = connAckPacket.Properties?.SharedSubscriptionAvailable, UserProperties = connAckPacket.Properties?.UserProperties }); }
public MqttClientConnectResult CreateClientConnectResult(MqttConnAckPacket connAckPacket) { if (connAckPacket == null) { throw new ArgumentNullException(nameof(connAckPacket)); } MqttClientConnectResultCode resultCode; switch (connAckPacket.ReturnCode) { case MqttConnectReturnCode.ConnectionAccepted: { resultCode = MqttClientConnectResultCode.Success; break; } case MqttConnectReturnCode.ConnectionRefusedUnacceptableProtocolVersion: { resultCode = MqttClientConnectResultCode.UnsupportedProtocolVersion; break; } case MqttConnectReturnCode.ConnectionRefusedNotAuthorized: { resultCode = MqttClientConnectResultCode.NotAuthorized; break; } case MqttConnectReturnCode.ConnectionRefusedBadUsernameOrPassword: { resultCode = MqttClientConnectResultCode.BadUserNameOrPassword; break; } case MqttConnectReturnCode.ConnectionRefusedIdentifierRejected: { resultCode = MqttClientConnectResultCode.ClientIdentifierNotValid; break; } case MqttConnectReturnCode.ConnectionRefusedServerUnavailable: { resultCode = MqttClientConnectResultCode.ServerUnavailable; break; } default: throw new MqttProtocolViolationException("Received unexpected return code."); } return(new MqttClientConnectResult { RetainAvailable = true, // Always true because v3.1.1 does not have a way to "disable" that feature. WildcardSubscriptionAvailable = true, // Always true because v3.1.1 does not have a way to "disable" that feature. IsSessionPresent = connAckPacket.IsSessionPresent, ResultCode = resultCode }); }
async Task <MqttClientConnection> CreateClientConnection( MqttConnectPacket connectPacket, MqttConnAckPacket connAckPacket, IMqttChannelAdapter channelAdapter, IDictionary <object, object> sessionItems) { MqttClientConnection connection; using (await _createConnectionSyncRoot.WaitAsync(CancellationToken.None).ConfigureAwait(false)) { MqttClientSession session; lock (_clientSessions) { if (!_clientSessions.TryGetValue(connectPacket.ClientId, out session)) { _logger.Verbose("Created a new session for client '{0}'.", connectPacket.ClientId); session = CreateSession(connectPacket.ClientId, sessionItems); } else { if (connectPacket.CleanSession) { _logger.Verbose("Deleting existing session of client '{0}'.", connectPacket.ClientId); session = CreateSession(connectPacket.ClientId, sessionItems); } else { _logger.Verbose("Reusing existing session of client '{0}'.", connectPacket.ClientId); connAckPacket.IsSessionPresent = true; } } _clientSessions[connectPacket.ClientId] = session; } MqttClientConnection existingConnection; lock (_clientConnections) { _clientConnections.TryGetValue(connectPacket.ClientId, out existingConnection); connection = CreateConnection(connectPacket, channelAdapter, session); _clientConnections[connectPacket.ClientId] = connection; } if (existingConnection != null) { await _eventDispatcher.SafeNotifyClientDisconnectedAsync(existingConnection.ClientId, MqttClientDisconnectType.Takeover, existingConnection.Endpoint); existingConnection.IsTakenOver = true; await existingConnection.StopAsync(MqttClientDisconnectReason.SessionTakenOver) .ConfigureAwait(false); } } return(connection); }
public MqttClientAuthenticateResult CreateClientConnectResult(MqttConnAckPacket connAckPacket) { if (connAckPacket == null) { throw new ArgumentNullException(nameof(connAckPacket)); } MqttClientConnectResultCode resultCode; switch (connAckPacket.ReturnCode.Value) { case MqttConnectReturnCode.ConnectionAccepted: { resultCode = MqttClientConnectResultCode.Success; break; } case MqttConnectReturnCode.ConnectionRefusedUnacceptableProtocolVersion: { resultCode = MqttClientConnectResultCode.UnsupportedProtocolVersion; break; } case MqttConnectReturnCode.ConnectionRefusedNotAuthorized: { resultCode = MqttClientConnectResultCode.NotAuthorized; break; } case MqttConnectReturnCode.ConnectionRefusedBadUsernameOrPassword: { resultCode = MqttClientConnectResultCode.BadUserNameOrPassword; break; } case MqttConnectReturnCode.ConnectionRefusedIdentifierRejected: { resultCode = MqttClientConnectResultCode.ClientIdentifierNotValid; break; } case MqttConnectReturnCode.ConnectionRefusedServerUnavailable: { resultCode = MqttClientConnectResultCode.ServerUnavailable; break; } default: throw new MqttProtocolViolationException("Received unexpected return code."); } return(new MqttClientAuthenticateResult { IsSessionPresent = connAckPacket.IsSessionPresent, ResultCode = resultCode }); }
public void DeserializeV310_MqttConnAckPacket() { var p = new MqttConnAckPacket { ReturnCode = MqttConnectReturnCode.ConnectionRefusedNotAuthorized }; DeserializeAndCompare(p, "IAIABQ==", MqttProtocolVersion.V310); }
public void SerializeV310_MqttConnAckPacket() { var p = new MqttConnAckPacket { ConnectReturnCode = MqttConnectReturnCode.ConnectionAccepted }; SerializeAndCompare(p, "IAIAAA==", MqttProtocolVersion.V310); }
public void DeserializeV311_MqttConnAckPacket() { var p = new MqttConnAckPacket { IsSessionPresent = true, ReturnCode = MqttConnectReturnCode.ConnectionRefusedNotAuthorized }; DeserializeAndCompare(p, "IAIBBQ=="); }
protected virtual MqttBasePacket DecodeConnAckPacket(IMqttPacketBodyReader body) { ThrowIfBodyIsEmpty(body); var packet = new MqttConnAckPacket(); body.ReadByte(); // Reserved. packet.ReturnCode = (MqttConnectReturnCode)body.ReadByte(); return(packet); }
private static byte EncodeConnAckPacket(MqttConnAckPacket packet, IMqttPacketWriter packetWriter) { if (packet == null) { throw new ArgumentNullException(nameof(packet)); } if (packetWriter == null) { throw new ArgumentNullException(nameof(packetWriter)); } if (!packet.ReasonCode.HasValue) { ThrowReasonCodeNotSetException(); } byte connectAcknowledgeFlags = 0x0; if (packet.IsSessionPresent) { connectAcknowledgeFlags |= 0x1; } packetWriter.Write(connectAcknowledgeFlags); packetWriter.Write((byte)packet.ReasonCode.Value); var propertiesWriter = new MqttV500PropertiesWriter(); if (packet.Properties != null) { propertiesWriter.WriteSessionExpiryInterval(packet.Properties.SessionExpiryInterval); propertiesWriter.WriteAuthenticationMethod(packet.Properties.AuthenticationMethod); propertiesWriter.WriteAuthenticationData(packet.Properties.AuthenticationData); propertiesWriter.WriteRetainAvailable(packet.Properties.RetainAvailable); propertiesWriter.WriteReceiveMaximum(packet.Properties.ReceiveMaximum); propertiesWriter.WriteMaximumQoS(packet.Properties.MaximumQoS); propertiesWriter.WriteAssignedClientIdentifier(packet.Properties.AssignedClientIdentifier); propertiesWriter.WriteTopicAliasMaximum(packet.Properties.TopicAliasMaximum); propertiesWriter.WriteReasonString(packet.Properties.ReasonString); propertiesWriter.WriteMaximumPacketSize(packet.Properties.MaximumPacketSize); propertiesWriter.WriteWildcardSubscriptionAvailable(packet.Properties.WildcardSubscriptionAvailable); propertiesWriter.WriteSubscriptionIdentifiersAvailable(packet.Properties.SubscriptionIdentifiersAvailable); propertiesWriter.WriteSharedSubscriptionAvailable(packet.Properties.SharedSubscriptionAvailable); propertiesWriter.WriteServerKeepAlive(packet.Properties.ServerKeepAlive); propertiesWriter.WriteResponseInformation(packet.Properties.ResponseInformation); propertiesWriter.WriteServerReference(packet.Properties.ServerReference); propertiesWriter.WriteUserProperties(packet.Properties.UserProperties); } propertiesWriter.WriteTo(packetWriter); return(MqttPacketWriter.BuildFixedHeader(MqttControlPacketType.ConnAck)); }
public void Serialize_Full_MqttConnAckPacket_V310() { var connAckPacket = new MqttConnAckPacket { AuthenticationData = Encoding.UTF8.GetBytes("AuthenticationData"), AuthenticationMethod = "AuthenticationMethod", ReasonCode = MqttConnectReasonCode.ServerUnavailable, ReasonString = "ReasonString", ReceiveMaximum = 123, ResponseInformation = "ResponseInformation", RetainAvailable = true, ReturnCode = MqttConnectReturnCode.ConnectionRefusedNotAuthorized, ServerReference = "ServerReference", AssignedClientIdentifier = "AssignedClientIdentifier", IsSessionPresent = true, MaximumPacketSize = 456, MaximumQoS = MqttQualityOfServiceLevel.ExactlyOnce, ServerKeepAlive = 789, SessionExpiryInterval = 852, SharedSubscriptionAvailable = true, SubscriptionIdentifiersAvailable = true, TopicAliasMaximum = 963, WildcardSubscriptionAvailable = true, UserProperties = new List <MqttUserProperty> { new MqttUserProperty("Foo", "Bar") } }; var deserialized = MqttPacketSerializationHelper.EncodeAndDecodePacket(connAckPacket, MqttProtocolVersion.V310); CollectionAssert.AreEqual(null, deserialized.AuthenticationData); // Not supported in v3.1.1 Assert.AreEqual(null, deserialized.AuthenticationMethod); // Not supported in v3.1.1 //Assert.AreEqual(connAckPacket.ReasonCode, deserialized.ReasonCode); Assert.AreEqual(null, deserialized.ReasonString); // Not supported in v3.1.1 Assert.AreEqual(0U, deserialized.ReceiveMaximum); // Not supported in v3.1.1 Assert.AreEqual(null, deserialized.ResponseInformation); // Not supported in v3.1.1 Assert.AreEqual(false, deserialized.RetainAvailable); // Not supported in v3.1.1 Assert.AreEqual(MqttConnectReturnCode.ConnectionRefusedNotAuthorized, deserialized.ReturnCode); Assert.AreEqual(null, deserialized.ServerReference); // Not supported in v3.1.1 Assert.AreEqual(null, deserialized.AssignedClientIdentifier); // Not supported in v3.1.1 Assert.AreEqual(false, deserialized.IsSessionPresent); // Not supported in v3.1.0 <- ! Assert.AreEqual(0U, deserialized.MaximumPacketSize); // Not supported in v3.1.1 Assert.AreEqual(MqttQualityOfServiceLevel.AtMostOnce, deserialized.MaximumQoS); // Not supported in v3.1.1 Assert.AreEqual(0U, deserialized.ServerKeepAlive); // Not supported in v3.1.1 Assert.AreEqual(0U, deserialized.SessionExpiryInterval); // Not supported in v3.1.1 Assert.AreEqual(false, deserialized.SharedSubscriptionAvailable); // Not supported in v3.1.1 Assert.AreEqual(false, deserialized.SubscriptionIdentifiersAvailable); // Not supported in v3.1.1 Assert.AreEqual(0U, deserialized.TopicAliasMaximum); // Not supported in v3.1.1 Assert.AreEqual(false, deserialized.WildcardSubscriptionAvailable); Assert.IsNull(deserialized.UserProperties); // Not supported in v3.1.1 }
private static MqttBasePacket DeserializeConnAck(MqttPacketReader reader) { var variableHeader1 = reader.ReadByte(); var variableHeader2 = reader.ReadByte(); var packet = new MqttConnAckPacket { IsSessionPresent = new ByteReader(variableHeader1).Read(), ConnectReturnCode = (MqttConnectReturnCode)variableHeader2 }; return(packet); }
MqttPacket DecodeConnAckPacket(ArraySegment <byte> body) { ThrowIfBodyIsEmpty(body); _bufferReader.SetBuffer(body.Array, body.Offset, body.Count); var packet = new MqttConnAckPacket(); _bufferReader.ReadByte(); // Reserved. packet.ReturnCode = (MqttConnectReturnCode)_bufferReader.ReadByte(); return(packet); }
public MqttClientAuthenticateResult CreateClientConnectResult(MqttConnAckPacket connAckPacket) { if (connAckPacket == null) { throw new ArgumentNullException(nameof(connAckPacket)); } return(new MqttClientAuthenticateResult { IsSessionPresent = connAckPacket.IsSessionPresent, ResultCode = (MqttClientConnectResultCode)connAckPacket.ReasonCode.Value }); }
protected override MqttBasePacket DecodeConnAckPacket(IMqttPacketBodyReader body) { ThrowIfBodyIsEmpty(body); var packet = new MqttConnAckPacket(); var acknowledgeFlags = body.ReadByte(); packet.IsSessionPresent = (acknowledgeFlags & 0x1) > 0; packet.ReturnCode = (MqttConnectReturnCode)body.ReadByte(); return(packet); }
public MqttClientConnectResult Create(MqttConnAckPacket connAckPacket, MqttProtocolVersion protocolVersion) { if (connAckPacket == null) { throw new ArgumentNullException(nameof(connAckPacket)); } if (protocolVersion == MqttProtocolVersion.V500) { return(CreateForMqtt500(connAckPacket)); } return(CreateForMqtt311(connAckPacket)); }
private byte Serialize(MqttConnAckPacket packet, MqttPacketWriter writer) { var connectAcknowledgeFlags = new ByteWriter(); if (ProtocolVersion == MqttProtocolVersion.V311) { connectAcknowledgeFlags.Write(packet.IsSessionPresent); } writer.Write(connectAcknowledgeFlags); writer.Write((byte)packet.ConnectReturnCode); return(MqttPacketWriter.BuildFixedHeader(MqttControlPacketType.ConnAck)); }
byte EncodeConnAckPacketV311(MqttConnAckPacket packet, MqttBufferWriter bufferWriter) { byte connectAcknowledgeFlags = 0x0; if (packet.IsSessionPresent) { connectAcknowledgeFlags |= 0x1; } bufferWriter.WriteByte(connectAcknowledgeFlags); bufferWriter.WriteByte((byte)packet.ReturnCode); return(MqttBufferWriter.BuildFixedHeader(MqttControlPacketType.ConnAck)); }
private async Task <MqttBasePacket> DeserializeConnAck(MqttPacketReader reader) { var variableHeader1 = await reader.ReadRemainingDataByteAsync(); var variableHeader2 = await reader.ReadRemainingDataByteAsync(); var packet = new MqttConnAckPacket { IsSessionPresent = new ByteReader(variableHeader1).Read(), ConnectReturnCode = (MqttConnectReturnCode)variableHeader2 }; return(packet); }
protected override byte EncodeConnAckPacket(MqttConnAckPacket packet, IMqttPacketWriter packetWriter) { byte connectAcknowledgeFlags = 0x0; if (packet.IsSessionPresent) { connectAcknowledgeFlags |= 0x1; } packetWriter.Write(connectAcknowledgeFlags); packetWriter.Write((byte)packet.ReturnCode); return(MqttPacketWriter.BuildFixedHeader(MqttControlPacketType.ConnAck)); }
private Task SerializeAsync(MqttConnAckPacket packet, IMqttCommunicationChannel destination) { using (var output = new MqttPacketWriter()) { var connectAcknowledgeFlags = new ByteWriter(); connectAcknowledgeFlags.Write(packet.IsSessionPresent); output.Write(connectAcknowledgeFlags); output.Write((byte)packet.ConnectReturnCode); output.InjectFixedHeader(MqttControlPacketType.ConnAck); return(output.WriteToAsync(destination)); } }
private MqttBasePacket DeserializeConnAck(MqttPacketReader reader) { var packet = new MqttConnAckPacket(); var firstByteReader = new ByteReader(reader.ReadByte()); if (ProtocolVersion == MqttProtocolVersion.V311) { packet.IsSessionPresent = firstByteReader.Read(); } packet.ConnectReturnCode = (MqttConnectReturnCode)reader.ReadByte(); return(packet); }
MqttPacket DecodeConnAckPacketV311(ArraySegment <byte> body) { ThrowIfBodyIsEmpty(body); _bufferReader.SetBuffer(body.Array, body.Offset, body.Count); var packet = new MqttConnAckPacket(); var acknowledgeFlags = _bufferReader.ReadByte(); packet.IsSessionPresent = (acknowledgeFlags & 0x1) > 0; packet.ReturnCode = (MqttConnectReturnCode)_bufferReader.ReadByte(); return(packet); }
static MqttClientConnectResult CreateForMqtt311(MqttConnAckPacket connAckPacket) { if (connAckPacket == null) { throw new ArgumentNullException(nameof(connAckPacket)); } return(new MqttClientConnectResult { RetainAvailable = true, // Always true because v3.1.1 does not have a way to "disable" that feature. WildcardSubscriptionAvailable = true, // Always true because v3.1.1 does not have a way to "disable" that feature. IsSessionPresent = connAckPacket.IsSessionPresent, ResultCode = ConvertReturnCodeToResultCode(connAckPacket.ReturnCode) }); }
private MqttBasePacket DeserializeConnAck(MqttPacketBodyReader body) { ThrowIfBodyIsEmpty(body); var packet = new MqttConnAckPacket(); var acknowledgeFlags = body.ReadByte(); if (ProtocolVersion == MqttProtocolVersion.V311) { packet.IsSessionPresent = (acknowledgeFlags & 0x1) > 0; } packet.ConnectReturnCode = (MqttConnectReturnCode)body.ReadByte(); return(packet); }
async Task <MqttClient> CreateClientConnection( MqttConnectPacket connectPacket, MqttConnAckPacket connAckPacket, IMqttChannelAdapter channelAdapter, ValidatingConnectionEventArgs validatingConnectionEventArgs) { MqttClient connection; bool sessionShouldPersist; if (validatingConnectionEventArgs.ProtocolVersion == MqttProtocolVersion.V500) { // MQTT 5.0 section 3.1.2.11.2 // The Client and Server MUST store the Session State after the Network Connection is closed if the Session Expiry Interval is greater than 0 [MQTT-3.1.2-23]. // // A Client that only wants to process messages while connected will set the Clean Start to 1 and set the Session Expiry Interval to 0. // It will not receive Application Messages published before it connected and has to subscribe afresh to any topics that it is interested // in each time it connects. // Persist if SessionExpiryInterval != 0, but may start with a clean session sessionShouldPersist = validatingConnectionEventArgs.SessionExpiryInterval != 0; } else { // MQTT 3.1.1 section 3.1.2.4: persist only if 'not CleanSession' // // If CleanSession is set to 1, the Client and Server MUST discard any previous Session and start a new one. // This Session lasts as long as the Network Connection. State data associated with this Session MUST NOT be // reused in any subsequent Session [MQTT-3.1.2-6]. sessionShouldPersist = !connectPacket.CleanSession; } using (await _createConnectionSyncRoot.WaitAsync(CancellationToken.None).ConfigureAwait(false)) { MqttSession session; lock (_sessionsManagementLock) { if (!_sessions.TryGetValue(connectPacket.ClientId, out session)) { session = CreateSession(connectPacket.ClientId, validatingConnectionEventArgs.SessionItems, sessionShouldPersist); } else { if (connectPacket.CleanSession) { _logger.Verbose("Deleting existing session of client '{0}'.", connectPacket.ClientId); session = CreateSession(connectPacket.ClientId, validatingConnectionEventArgs.SessionItems, sessionShouldPersist); } else { _logger.Verbose("Reusing existing session of client '{0}'.", connectPacket.ClientId); // Session persistence could change for MQTT 5 clients that reconnect with different SessionExpiryInterval session.IsPersistent = sessionShouldPersist; connAckPacket.IsSessionPresent = true; session.Recover(); } } _sessions[connectPacket.ClientId] = session; } if (!connAckPacket.IsSessionPresent) { // TODO: This event is not yet final. It can already be used but restoring sessions from storage will be added later! var preparingSessionEventArgs = new PreparingSessionEventArgs(); await _eventContainer.PreparingSessionEvent.InvokeAsync(preparingSessionEventArgs).ConfigureAwait(false); } MqttClient existing; lock (_clients) { _clients.TryGetValue(connectPacket.ClientId, out existing); connection = CreateConnection(connectPacket, channelAdapter, session); _clients[connectPacket.ClientId] = connection; } if (existing != null) { existing.IsTakenOver = true; await existing.StopAsync(MqttDisconnectReasonCode.SessionTakenOver).ConfigureAwait(false); if (_eventContainer.ClientConnectedEvent.HasHandlers) { var eventArgs = new ClientDisconnectedEventArgs { ClientId = existing.Id, DisconnectType = MqttClientDisconnectType.Takeover, Endpoint = existing.Endpoint }; await _eventContainer.ClientDisconnectedEvent.InvokeAsync(eventArgs).ConfigureAwait(false); } } } return(connection); }