/// <summary> /// Unsubscribe for message topics /// </summary> /// <param name="topics">List of topics to unsubscribe</param> /// <returns>Message Id in UNSUBACK message from broker</returns> public ushort Unsubscribe(string[] topics) { int attempts = 0; bool acknowledged = false; MqttMsgUnsubscribe unsubscribe = new MqttMsgUnsubscribe(topics); MqttMsgUnsuback unsuback = null; do { try { // try unsubscribe unsuback = (MqttMsgUnsuback)this.SendReceive(unsubscribe.GetBytes()); acknowledged = true; } catch (MqttTimeoutException) { // no UNSUBACK message received in time, retry with duplicate flag attempts++; unsubscribe.DupFlag = true; // delay before retry if (attempts < MQTT_ATTEMPTS_RETRY) { Thread.Sleep(MQTT_DELAY_RETRY); } } } while ((attempts < MQTT_ATTEMPTS_RETRY) && !acknowledged); // return message id from SUBACK or zero (no message id) return(acknowledged ? unsuback.MessageId : (ushort)0); }
public void Unsubscribe(string clientId, MqttMsgUnsubscribe packet) { try { Session session = SessionManager.sessions.First(ss => ss.ClientId == clientId); List <Subscription> subs = session.Subscriptions; lock (subs) { for (int i = 0; i < packet.Topics.Length; i++) { string topicReplaced = packet.Topics[i].Replace(PLUS_WILDCARD, PLUS_WILDCARD_REPLACE).Replace(SHARP_WILDCARD, SHARP_WILDCARD_REPLACE); topicReplaced = "^" + topicReplaced + "$"; if (subs != null) { subs.Remove(subs.First(s => s.Topic == topicReplaced)); } } } } catch (Exception) { throw new ArgumentNullException("Couldn't find the client in subscriptions"); } }
private void HandleUNSUBSCRIBEType(uint clientIndex, MqttMsgUnsubscribe packet, bool isWebSocketClient) { CrestronLogger.WriteToLog("MQTTSERVER - HandleUNSUBSCRIBEType - Unsubscribe Received" + packet.ToString(), 1); sessionManager.Unsubscribe(GetClientByIndex(clientIndex, isWebSocketClient).ClientId, packet); byte[] unSubAckBytes = MsgBuilder.BuildUnSubAck(packet.MessageId).GetBytes(); Send(clientIndex, unSubAckBytes, unSubAckBytes.Length, isWebSocketClient); }
public void UnbscribeBasicEncodeTestv5() { // Arrange byte[] encodedCorrect = new byte[] { 162, 19, 0, 42, 0, 0, 6, 116, 112, 111, 105, 99, 49, 0, 6, 116, 111, 112, 105, 99, 50 }; MqttMsgUnsubscribe unsubscribe = new MqttMsgUnsubscribe(new string[] { "tpoic1", "topic2" }); unsubscribe.MessageId = 42; // Act byte[] encoded = unsubscribe.GetBytes(MqttProtocolVersion.Version_5); // Assert Assert.Equal(encodedCorrect, encoded); }
public void UnbscribeBasicDecodeTestv5() { // Arrange byte[] encodedCorrect = new byte[] { 19, 0, 42, 0, 0, 6, 116, 112, 111, 105, 99, 49, 0, 6, 116, 111, 112, 105, 99, 50 }; MokChannel mokChannel = new(encodedCorrect); // Act MqttMsgUnsubscribe unsubscribe = MqttMsgUnsubscribe.Parse(162, MqttProtocolVersion.Version_5, mokChannel); // Assert Assert.Equal((ushort)42, unsubscribe.MessageId); Assert.Equal(unsubscribe.Topics.Length, 2); Assert.Equal(unsubscribe.Topics, new string[] { "tpoic1", "topic2" }); }
public void UnbscribeAdvanceEncodeTestv5() { // Arrange byte[] encodedCorrect = new byte[] { 162, 54, 0, 42, 35, 38, 0, 4, 80, 114, 111, 112, 0, 26, 111, 110, 108, 121, 32, 111, 110, 101, 32, 116, 104, 105, 115, 32, 116, 105, 109, 101, 32, 102, 111, 114, 32, 102, 117, 110, 0, 6, 116, 112, 111, 105, 99, 49, 0, 6, 116, 111, 112, 105, 99, 50 }; MqttMsgUnsubscribe unsubscribe = new MqttMsgUnsubscribe(new string[] { "tpoic1", "topic2" }); unsubscribe.MessageId = 42; unsubscribe.UserProperties.Add(new UserProperty("Prop", "only one this time for fun")); // Act byte[] encoded = unsubscribe.GetBytes(MqttProtocolVersion.Version_5); Helpers.DumpBuffer(encoded); // Assert Assert.Equal(encodedCorrect, encoded); }
public void UnbscribeAdvanceDecodeTestv5() { // Arrange byte[] encodedCorrect = new byte[] { 54, 0, 42, 35, 38, 0, 4, 80, 114, 111, 112, 0, 26, 111, 110, 108, 121, 32, 111, 110, 101, 32, 116, 104, 105, 115, 32, 116, 105, 109, 101, 32, 102, 111, 114, 32, 102, 117, 110, 0, 6, 116, 112, 111, 105, 99, 49, 0, 6, 116, 111, 112, 105, 99, 50 }; MokChannel mokChannel = new(encodedCorrect); // Act MqttMsgUnsubscribe unsubscribe = MqttMsgUnsubscribe.Parse(162, MqttProtocolVersion.Version_5, mokChannel); // Assert Assert.Equal((ushort)42, unsubscribe.MessageId); Assert.Equal(unsubscribe.Topics.Length, 2); Assert.Equal(unsubscribe.Topics, new string[] { "tpoic1", "topic2" }); var prop = new UserProperty("Prop", "only one this time for fun"); Assert.Equal(((UserProperty)unsubscribe.UserProperties[0]).Name, prop.Name); Assert.Equal(((UserProperty)unsubscribe.UserProperties[0]).Value, prop.Value); }
public static MqttMsgBase DecodeControlPacket(byte[] data) { byte fixedHeaderFirstByte = (byte)(data[0] >> MqttMsgBase.MSG_TYPE_OFFSET); switch (fixedHeaderFirstByte) { case MqttMsgBase.MQTT_MSG_CONNECT_TYPE: { return(MqttMsgConnect.Parse(data)); } case MqttMsgBase.MQTT_MSG_CONNACK_TYPE: { return(MqttMsgConnack.Parse(data)); } case MqttMsgBase.MQTT_MSG_PUBLISH_TYPE: { return(MqttMsgPublish.Parse(data)); } case MqttMsgBase.MQTT_MSG_PUBACK_TYPE: { return(MqttMsgPuback.Parse(data)); } case MqttMsgBase.MQTT_MSG_PUBREC_TYPE: { return(MqttMsgPubrec.Parse(data)); } case MqttMsgBase.MQTT_MSG_PUBREL_TYPE: { return(MqttMsgPubrel.Parse(data)); } case MqttMsgBase.MQTT_MSG_PUBCOMP_TYPE: { return(MqttMsgPubcomp.Parse(data)); } case MqttMsgBase.MQTT_MSG_SUBSCRIBE_TYPE: { return(MqttMsgSubscribe.Parse(data)); } case MqttMsgBase.MQTT_MSG_SUBACK_TYPE: { return(MqttMsgSuback.Parse(data)); } case MqttMsgBase.MQTT_MSG_UNSUBSCRIBE_TYPE: { return(MqttMsgUnsubscribe.Parse(data)); } case MqttMsgBase.MQTT_MSG_UNSUBACK_TYPE: { return(MqttMsgUnsuback.Parse(data)); } case MqttMsgBase.MQTT_MSG_PINGREQ_TYPE: { return(MqttMsgPingReq.Parse(data)); } case MqttMsgBase.MQTT_MSG_PINGRESP_TYPE: { return(MqttMsgPingResp.Parse(data)); } case MqttMsgBase.MQTT_MSG_DISCONNECT_TYPE: { CrestronLogger.WriteToLog("PACKETDECODER - Riconosciuto DISCONNNECT: ", 1); return(MqttMsgDisconnect.Parse(data)); } default: { throw new FormatException(); } } }
internal void Unsubscribe(string clientId, MqttMsgUnsubscribe packet) { subscriptionManager.Unsubscribe(clientId, packet); }
public MqttMsgBase DecodeControlPacket(byte[] data) { byte fixedHeaderFirstByte = (byte)(data[0] >> MSG_TYPE_OFFSET); switch (fixedHeaderFirstByte) { case MqttMsgBase.MQTT_MSG_CONNECT_TYPE: { return(MqttMsgConnect.Parse(data)); } case MqttMsgBase.MQTT_MSG_CONNACK_TYPE: { return(MqttMsgConnack.Parse(data)); } case MqttMsgBase.MQTT_MSG_PUBLISH_TYPE: { return(MqttMsgPublish.Parse(data)); } case MqttMsgBase.MQTT_MSG_PUBACK_TYPE: { return(MqttMsgPuback.Parse(data)); } case MqttMsgBase.MQTT_MSG_PUBREC_TYPE: { return(MqttMsgPubrec.Parse(data)); } case MqttMsgBase.MQTT_MSG_PUBREL_TYPE: { return(MqttMsgPubrel.Parse(data)); } case MqttMsgBase.MQTT_MSG_PUBCOMP_TYPE: { return(MqttMsgPubcomp.Parse(data)); } case MqttMsgBase.MQTT_MSG_SUBSCRIBE_TYPE: { return(MqttMsgSubscribe.Parse(data)); } case MqttMsgBase.MQTT_MSG_SUBACK_TYPE: { return(MqttMsgSuback.Parse(data)); } case MqttMsgBase.MQTT_MSG_UNSUBSCRIBE_TYPE: { return(MqttMsgUnsubscribe.Parse(data)); } case MqttMsgBase.MQTT_MSG_UNSUBACK_TYPE: { return(MqttMsgUnsuback.Parse(data)); } case MqttMsgBase.MQTT_MSG_PINGREQ_TYPE: { return(MqttMsgPingReq.Parse(data)); } case MqttMsgBase.MQTT_MSG_PINGRESP_TYPE: { return(MqttMsgPingResp.Parse(data)); } case MqttMsgBase.MQTT_MSG_DISCONNECT_TYPE: { return(MqttMsgDisconnect.Parse(data)); } default: { throw new FormatException(" First byte shifted : " + fixedHeaderFirstByte); } } }
public void ProcessReceivedMessage(MqttRawMessage rawMessage) { if (!rawMessage.Connection.IsRunning) { return; } // update last message received ticks rawMessage.Connection.LastCommunicationTime = Environment.TickCount; // extract message type from received byte var msgType = (byte)((rawMessage.MessageType & MqttMsgBase.MSG_TYPE_MASK) >> MqttMsgBase.MSG_TYPE_OFFSET); var protocolVersion = (byte)rawMessage.Connection.ProtocolVersion; switch (msgType) { case MqttMsgBase.MQTT_MSG_CONNECT_TYPE: var connect = MqttMsgConnect.Parse( rawMessage.MessageType, protocolVersion, rawMessage.PayloadBuffer); rawMessage.Connection.EnqueueInternalEvent(new InternalEvent(connect)); break; case MqttMsgBase.MQTT_MSG_PINGREQ_TYPE: var pingReqest = MqttMsgPingReq.Parse(rawMessage.MessageType, protocolVersion); outgoingMessageHandler.PingResp(rawMessage.Connection); break; case MqttMsgBase.MQTT_MSG_SUBSCRIBE_TYPE: var subscribe = MqttMsgSubscribe.Parse( rawMessage.MessageType, protocolVersion, rawMessage.PayloadBuffer, rawMessage.PayloadLength); rawMessage.Connection.EnqueueInternalEvent(new InternalEvent(subscribe)); break; case MqttMsgBase.MQTT_MSG_PUBLISH_TYPE: var publish = MqttMsgPublish.Parse( rawMessage.MessageType, protocolVersion, rawMessage.PayloadBuffer, rawMessage.PayloadLength); EnqueueInflight(rawMessage.Connection, publish, MqttMsgFlow.ToAcknowledge); break; case MqttMsgBase.MQTT_MSG_PUBACK_TYPE: // enqueue PUBACK message received (for QoS Level 1) into the internal queue var puback = MqttMsgPuback.Parse( rawMessage.MessageType, protocolVersion, rawMessage.PayloadBuffer); EnqueueInternal(rawMessage.Connection, puback); break; case MqttMsgBase.MQTT_MSG_PUBREC_TYPE: // enqueue PUBREC message received (for QoS Level 2) into the internal queue var pubrec = MqttMsgPubrec.Parse( rawMessage.MessageType, protocolVersion, rawMessage.PayloadBuffer); EnqueueInternal(rawMessage.Connection, pubrec); break; case MqttMsgBase.MQTT_MSG_PUBREL_TYPE: // enqueue PUBREL message received (for QoS Level 2) into the internal queue var pubrel = MqttMsgPubrel.Parse( rawMessage.MessageType, protocolVersion, rawMessage.PayloadBuffer); EnqueueInternal(rawMessage.Connection, pubrel); break; case MqttMsgBase.MQTT_MSG_PUBCOMP_TYPE: // enqueue PUBCOMP message received (for QoS Level 2) into the internal queue var pubcomp = MqttMsgPubcomp.Parse( rawMessage.MessageType, protocolVersion, rawMessage.PayloadBuffer); EnqueueInternal(rawMessage.Connection, pubcomp); break; case MqttMsgBase.MQTT_MSG_UNSUBSCRIBE_TYPE: var unsubscribe = MqttMsgUnsubscribe.Parse( rawMessage.MessageType, protocolVersion, rawMessage.PayloadBuffer, rawMessage.PayloadLength); rawMessage.Connection.EnqueueInternalEvent(new InternalEvent(unsubscribe)); break; case MqttMsgBase.MQTT_MSG_DISCONNECT_TYPE: var disconnect = MqttMsgDisconnect.Parse(rawMessage.MessageType, protocolVersion); rawMessage.Connection.EnqueueInternalEvent(new InternalEvent(disconnect)); break; case MqttMsgBase.MQTT_MSG_CONNACK_TYPE: case MqttMsgBase.MQTT_MSG_PINGRESP_TYPE: case MqttMsgBase.MQTT_MSG_SUBACK_TYPE: case MqttMsgBase.MQTT_MSG_UNSUBACK_TYPE: throw new MqttClientException(MqttClientErrorCode.WrongBrokerMessage); default: throw new MqttClientException(MqttClientErrorCode.WrongBrokerMessage); } }
public MqttMsgBase DecodeControlPacket(byte[] data) { #if PACKET_DEBUG CrestronLogger.WriteToLog("MQTTCLIENT - RECEIVE - " + BitConverter.ToString(data), 2); #endif byte fixedHeaderFirstByte = (byte)(data[0] >> MSG_TYPE_OFFSET); switch (fixedHeaderFirstByte) { case MqttMsgBase.MQTT_MSG_CONNECT_TYPE: { return(MqttMsgConnect.Parse(data)); } case MqttMsgBase.MQTT_MSG_CONNACK_TYPE: { return(MqttMsgConnack.Parse(data)); } case MqttMsgBase.MQTT_MSG_PUBLISH_TYPE: { return(MqttMsgPublish.Parse(data)); } case MqttMsgBase.MQTT_MSG_PUBACK_TYPE: { return(MqttMsgPuback.Parse(data)); } case MqttMsgBase.MQTT_MSG_PUBREC_TYPE: { return(MqttMsgPubrec.Parse(data)); } case MqttMsgBase.MQTT_MSG_PUBREL_TYPE: { return(MqttMsgPubrel.Parse(data)); } case MqttMsgBase.MQTT_MSG_PUBCOMP_TYPE: { return(MqttMsgPubcomp.Parse(data)); } case MqttMsgBase.MQTT_MSG_SUBSCRIBE_TYPE: { return(MqttMsgSubscribe.Parse(data)); } case MqttMsgBase.MQTT_MSG_SUBACK_TYPE: { return(MqttMsgSuback.Parse(data)); } case MqttMsgBase.MQTT_MSG_UNSUBSCRIBE_TYPE: { return(MqttMsgUnsubscribe.Parse(data)); } case MqttMsgBase.MQTT_MSG_UNSUBACK_TYPE: { return(MqttMsgUnsuback.Parse(data)); } case MqttMsgBase.MQTT_MSG_PINGREQ_TYPE: { return(MqttMsgPingReq.Parse(data)); } case MqttMsgBase.MQTT_MSG_PINGRESP_TYPE: { return(MqttMsgPingResp.Parse(data)); } case MqttMsgBase.MQTT_MSG_DISCONNECT_TYPE: { return(MqttMsgDisconnect.Parse(data)); } default: { throw new FormatException(" First byte shifted : " + fixedHeaderFirstByte); } } }
public static void ProcessInternalEventQueue(MqttClientConnection clientConnection) { if (!clientConnection.IsRunning) { return; } InternalEvent internalEvent; if (clientConnection.EventQueue.TryDequeue(out internalEvent)) { MqttMsgBase msg = ((MsgInternalEvent)internalEvent).Message; if (msg != null) { switch (msg.Type) { // CONNECT message received case MqttMsgBase.MQTT_MSG_CONNECT_TYPE: clientConnection.OnMqttMsgConnected((MqttMsgConnect)msg); break; // SUBSCRIBE message received case MqttMsgBase.MQTT_MSG_SUBSCRIBE_TYPE: MqttMsgSubscribe subscribe = (MqttMsgSubscribe)msg; clientConnection.OnMqttMsgSubscribeReceived(subscribe.MessageId, subscribe.Topics, subscribe.QoSLevels); break; // SUBACK message received case MqttMsgBase.MQTT_MSG_SUBACK_TYPE: OnMqttMsgSubscribed(clientConnection, (MqttMsgSuback)msg); break; // PUBLISH message received case MqttMsgBase.MQTT_MSG_PUBLISH_TYPE: // PUBLISH message received in a published internal event, no publish succeeded if (internalEvent.GetType() == typeof(MsgPublishedInternalEvent)) { OnMqttMsgPublished(clientConnection, msg.MessageId, false); } else { // raise PUBLISH message received event clientConnection.OnMqttMsgPublishReceived((MqttMsgPublish)msg); } break; // (PUBACK received for QoS Level 1) case MqttMsgBase.MQTT_MSG_PUBACK_TYPE: OnMqttMsgPublished(clientConnection, msg.MessageId, true); break; // (PUBREL received for QoS Level 2) case MqttMsgBase.MQTT_MSG_PUBREL_TYPE: clientConnection.OnMqttMsgPublishReceived((MqttMsgPublish)msg); break; // (PUBCOMP received for QoS Level 2) case MqttMsgBase.MQTT_MSG_PUBCOMP_TYPE: OnMqttMsgPublished(clientConnection, msg.MessageId, true); break; // UNSUBSCRIBE message received from client case MqttMsgBase.MQTT_MSG_UNSUBSCRIBE_TYPE: MqttMsgUnsubscribe unsubscribe = (MqttMsgUnsubscribe)msg; OnMqttMsgUnsubscribeReceived(clientConnection, unsubscribe.MessageId, unsubscribe.Topics); break; // UNSUBACK message received case MqttMsgBase.MQTT_MSG_UNSUBACK_TYPE: OnMqttMsgUnsubscribed(clientConnection, msg.MessageId); break; // DISCONNECT message received from client case MqttMsgBase.MQTT_MSG_DISCONNECT_TYPE: OnMqttMsgDisconnected(clientConnection); break; } } } // all events for received messages dispatched, check if there is closing connection if ((clientConnection.EventQueue.Count == 0) && clientConnection.IsConnectionClosing) { // client raw disconnection clientConnection.OnConnectionClosed(); } }