private async void CheckForClientTimeout(MqttClientConnection clientConnection) { await Task.Delay(clientConnection.Settings.TimeoutOnConnection); // broker need to receive the first message (CONNECT) // within a reasonable amount of time after TCP/IP connection // wait on receiving message from client with a connection timeout if (clientConnection.IsRunning && !clientConnection.IsConnected && clientConnection.EventQueue.IsEmpty) { clientConnection.OnConnectionClosed(); } }
public static void Connack(MqttClientConnection clientConnection, MqttMsgConnect connect, byte returnCode, string clientId, bool sessionPresent) { clientConnection.LastCommunicationTime = Environment.TickCount; MqttMsgConnack connack = new MqttMsgConnack(); connack.ReturnCode = returnCode; if (clientConnection.ProtocolVersion == MqttProtocolVersion.Version_3_1_1) { connack.SessionPresent = sessionPresent; } // ... send it to the client Send(clientConnection, connack); // connection accepted, start keep alive thread checking if (returnCode == MqttMsgConnack.CONN_ACCEPTED) { // [v3.1.1] if client id isn't null, the CONNECT message has a cliend id with zero bytes length // and broker assigned a unique identifier to the client clientConnection.ClientId = (clientId == null) ? connect.ClientId : clientId; clientConnection.CleanSession = connect.CleanSession; clientConnection.WillFlag = connect.WillFlag; clientConnection.WillTopic = connect.WillTopic; clientConnection.WillMessage = connect.WillMessage; clientConnection.WillQosLevel = connect.WillQosLevel; clientConnection.KeepAlivePeriod = connect.KeepAlivePeriod * 1000; // convert in ms // broker has a tolerance of 1.5 specified keep alive period clientConnection.KeepAlivePeriod += (clientConnection.KeepAlivePeriod / 2); clientConnection.IsConnectionClosing = false; clientConnection.IsConnected = true; } // connection refused, close TCP/IP channel else { clientConnection.OnConnectionClosed(); } }
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(); } }
private static void OnMqttMsgDisconnected(MqttClientConnection clientConnection) { // close the client clientConnection.OnConnectionClosed(); }