protected void handleMessage(ConnAckMessage msg) { connackReceived = true; if (msg.getStatus() != ConnAckMessage.ConnectionStatus.ACCEPTED) { connectCallback.onFailure(new ConnectionException("Unable to connect to server", msg.getStatus())); return; } if (mqttListener != null) { mqttListener.onConnected(); } connectCallback.onSuccess(); }
/// <summary> /// reads message from messagestream buffer. It reads first byte of flags, which is passed further to restore buffer /// if buffer does not contains complete message as of now. An exception is thrown which is ignored by caller /// </summary> /// <returns></returns> public Message readMessage() { byte flags = input.readByte(); Header header = new Header(flags); Message msg = null; MessageType type = header.getType(); switch (type) { case MessageType.CONNACK: msg = new ConnAckMessage(header, this); break; case MessageType.PUBLISH: msg = new PublishMessage(header, this); break; case MessageType.PUBACK: msg = new PubAckMessage(header, this); break; case MessageType.PUBREC: msg = new PubRecMessage(header, this); break; case MessageType.PUBREL: msg = new PubRelMessage(header, this); break; case MessageType.SUBACK: msg = new SubAckMessage(header, this); break; case MessageType.SUBSCRIBE: msg = new SubscribeMessage(header, this); break; case MessageType.UNSUBACK: msg = new UnsubAckMessage(header, this); break; case MessageType.PINGRESP: msg = new PingRespMessage(header, this); break; case MessageType.PINGREQ: msg = new PingReqMessage(header, this); break; case MessageType.DISCONNECT: msg = new DisconnectMessage(header, this); break; case MessageType.CONNECT: msg = new ConnectMessage(header, this); break; default: throw new NotSupportedException("No support for deserializing " + header.getType() + " messages"); } try { msg.read(input); } catch (IndexOutOfRangeException outOfRange) { throw outOfRange; } return(msg); }
private async void handleConnection(TcpClient connection) { var ep = connection.Client.RemoteEndPoint; Console.WriteLine("New Connection from {0}", ep); NetworkStream stream = connection.GetStream(); MqttMessage message = await MqttMessage.Read(stream, 5); if (message.Type != MessageType.Connect) { throw new MqttProtocolException("First packet not connect"); } //TODO: Non-clean sessions ConnAckMessage connAck = new ConnAckMessage(0, false); await connAck.Write(stream); ConnectMessage connectMessage = (ConnectMessage)message; double keepalive = ((ConnectMessage)message).KeepAlive * 1.5; String clientId = ((ConnectMessage)message).ClientId; if (String.IsNullOrEmpty(clientId)) { clientId = Guid.NewGuid().ToString(); } IMqttSession session = await sessionProvider.NewSession(clientId); Console.WriteLine("Client {0} connected from {1} ({2},{3})", clientId, ep, connectMessage.CleanSession, connectMessage.KeepAlive); connections.Add(session, connection); Task <MqttMessage> incoming = MqttMessage.Read(stream); Task <PendingMessage> outgoing = session.NextPending(null, 0); while (connection.Connected) { try { if (await Task.WhenAny(incoming, outgoing) == incoming) { try { message = incoming.Result; } catch (AggregateException e) { Console.WriteLine(e.InnerException.Message); connections.Remove(session); connection.Close(); continue; } catch (Exception e) { Console.WriteLine(e.Message); connections.Remove(session); connection.Close(); continue; } switch (message.Type) { case MessageType.Publish: await PublishReceived(session, stream, (PublishMessage)message); break; case MessageType.Disconnect: Console.WriteLine("Client {0} disconnected cleanly", clientId); connections.Remove(session); connection.Close(); //Skip reading the next message. Loop should exit. continue; case MessageType.Subscribe: await SubscribeReceived(session, stream, (SubscribeMessage)message); break; case MessageType.Unsubscribe: await sessionProvider.RemoveSubscriptions(session, ((UnsubscribeMessage)message).TopicFilters); await new UnsubAckMessage(((UnsubscribeMessage)message).PacketId).Write(stream); break; case MessageType.PubAck: string messageId = await session.PublishAcknowledged(((PubAckMessage)message).PacketId); if (messageId != null) { await storageProvider.ReleaseMessage(messageId); } break; case MessageType.PubRec: messageId = await session.PublishReceived(((PubRecMessage)message).PacketId); if (messageId != null) { await storageProvider.ReleaseMessage(messageId); } break; case MessageType.PubRel: await session.RemoveQoS2(((PubRelMessage)message).PacketId); await new PubCompMessage(((PubRelMessage)message).PacketId).Write(stream); break; case MessageType.PubComp: await session.PublishCompleted(((PubCompMessage)message).PacketId); break; case MessageType.PingReq: await new PingRespMessage().Write(stream); break; } incoming = MqttMessage.Read(stream); } else { PendingMessage pendingMessage = outgoing.Result; PendingPublishMessage pendingPublish = pendingMessage as PendingPublishMessage; if (pendingPublish != null) { var messageInfo = await storageProvider.GetMessage(pendingPublish.MessageId); message = new PublishMessage(pendingPublish.Duplicate, false, pendingPublish.QoS, messageInfo.Topic, messageInfo.Payload, pendingPublish.PacketId); } else { message = new PubRelMessage(pendingMessage.PacketId); } await message.Write(stream); outgoing = session.NextPending(pendingMessage, 5000); } } catch (Exception e) { Console.Out.WriteLine(e.Message); } } await sessionProvider.CloseSession(session); }