Exemplo n.º 1
0
 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();
 }
Exemplo n.º 2
0
        /// <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);
        }
Exemplo n.º 3
0
        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);
        }