示例#1
0
        public override Task Start(MqttCommand msg, Action <MqttCommand> release)
        {
            if (release == null)
            {
                release = p => { };
            }

            switch (msg.Header.QualityOfService)
            {
            case QualityOfService.AtMostOnce:
                return(Task.Factory.StartNew(() => release(msg), TaskCreationOptions.LongRunning));

            case QualityOfService.AtLeastOnce:
                return(Send(new PubAck(msg.MessageId))
                       .ContinueWith(task =>
                                     release(msg),
                                     TaskContinuationOptions.OnlyOnRanToCompletion | TaskContinuationOptions.LongRunning));

            case QualityOfService.ExactlyOnce:
                return(Send(new PubRec(msg.MessageId))
                       .ContinueWith(task =>
                                     WaitFor(CommandMessage.PUBREL, msg.MessageId, TimeSpan.FromSeconds(60)),
                                     TaskContinuationOptions.OnlyOnRanToCompletion | TaskContinuationOptions.LongRunning)
                       .ContinueWith(task =>
                                     Send(new PubComp(msg.MessageId)),
                                     TaskContinuationOptions.OnlyOnRanToCompletion | TaskContinuationOptions.LongRunning)
                       .ContinueWith(task =>
                                     release(msg),
                                     TaskContinuationOptions.OnlyOnRanToCompletion | TaskContinuationOptions.LongRunning));

            default:
                throw new InvalidOperationException("Unknown QoS");
            }
        }
示例#2
0
        private void EnqueueResponse(MqttCommand command)
        {
            MessageReceivedCallback recv = OnMessageReceived;

            switch (command.CommandMessage)
            {
            case Types.CommandMessage.CONNECT:
                if (recv != null)
                {
                    recv(this, new ClientCommandEventArgs(new ConnAck()));
                }
                break;

            case Types.CommandMessage.PINGREQ:
                if (SendPingResponses)
                {
                    if (recv != null)
                    {
                        recv(this, new ClientCommandEventArgs(new PingResp()));
                    }
                }
                break;

            case Types.CommandMessage.DISCONNECT:
                break;

            default:
                throw new NotImplementedException();
            }
        }
示例#3
0
        internal void Complete(MqttCommand command)
        {
            System.Diagnostics.Debug.WriteLine("FINISHED: {0} {1}", command.CommandMessage, command.MessageId);

            switch (command.CommandMessage)
            {
            case CommandMessage.SUBSCRIBE:
                ActiveSubscriptions.Current.Add(ClientId, (command as Subscribe).Subscriptions);
                break;

            case CommandMessage.PUBLISH:
                foreach (string client in ActiveSubscriptions.Current.Publish(ClientId, (command as Publish).Topic, (command as Publish).Message))
                {
                    Manager.Send(client, new Publish((command as Publish).Topic, (command as Publish).Message));
                }
                break;

            case CommandMessage.UNSUBSCRIBE:
                ActiveSubscriptions.Current.Remove(ClientId, (command as Unsubscribe).Topics);
                break;

            case CommandMessage.PINGREQ:
                Send(new PingReq());
                break;

            case CommandMessage.DISCONNECT:
                ActiveSubscriptions.Current.Remove(ClientId);
                Connection.Disconnect();
                Manager.Disconnect(this);
                break;
            }
        }
示例#4
0
文件: Client.cs 项目: hezlog/MQTT
        private void _broker_OnMessageReceived(object sender, ClientCommandEventArgs e)
        {
            MqttCommand command = e.Command;

            Debug.WriteLine("RECV: {0} ({1})", command.CommandMessage, command.MessageId);

            lock (_lastHeaderLock)
            {
                _lastHeard = DateTime.UtcNow;
            }

            switch (command.CommandMessage)
            {
            case CommandMessage.PUBACK:
            case CommandMessage.PUBCOMP:
            case CommandMessage.PUBREC:
            case CommandMessage.PUBREL:
            case CommandMessage.SUBACK:
            case CommandMessage.CONNACK:
            case CommandMessage.UNSUBACK:
                _manager.Deliver(command);
                break;

            case CommandMessage.PINGRESP:
                // ignore (we sent it) - eventually track
                break;

            default:
                _manager.StartNew(command, Notify);
                break;
            }
        }
示例#5
0
        private void ClientOnMessageReceived(object sender, ClientCommandEventArgs e)
        {
            MqttCommand command = e.Command;

            Debug.WriteLine("{0} : Recevied Message {1} id {2}", DateTime.Now.ToString("o"), command.CommandMessage,
                            command.MessageId);

            switch (command.CommandMessage)
            {
            case CommandMessage.PUBACK:
            case CommandMessage.PUBCOMP:
            case CommandMessage.PUBREC:
            case CommandMessage.PUBREL:
            case CommandMessage.SUBACK:
            case CommandMessage.CONNACK:
            case CommandMessage.UNSUBACK:
            case CommandMessage.PINGRESP:
                _manager.Deliver(command);
                break;

            default:
                _manager.StartNew(command, Notify);
                break;
            }
        }
示例#6
0
        public Task StartNew(MqttCommand command, Action <MqttCommand> onSuccess)
        {
            switch (command.CommandMessage)
            {
            case CommandMessage.CONNECT:
                var connFlow = new ConnectReceiveFlow(this);
                return(connFlow.Start(command, onSuccess));

            case CommandMessage.PUBLISH:
                var pubFlow = new PublishReceiveFlow(this);
                return(pubFlow.Start(command, onSuccess));

            case CommandMessage.SUBSCRIBE:
                var subFlow = new SubscribeFlow(this);
                return(subFlow.Start(command, onSuccess));

            case CommandMessage.PINGREQ:
                var pingFlow = new PingSendFlow(this);
                return(pingFlow.Start(command, onSuccess));

            default:
                var tcs = new TaskCompletionSource <object>();
                tcs.SetException(new InvalidOperationException("Unhandled command type"));
                return(tcs.Task);
            }
        }
示例#7
0
        public override Task Start(MqttCommand msg, Action <MqttCommand> release)
        {
            if (release == null)
            {
                release = (MqttCommand p) => { };
            }
            switch (msg.Header.QualityOfService)
            {
            case QualityOfService.AtLeastOnce:
                return(Send(msg)
                       .ContinueWith((task) =>
                                     WaitFor(CommandMessage.SUBACK, msg.MessageId, TimeSpan.FromSeconds(30)))
                       .ContinueWith((task) =>
                                     release(msg),
                                     TaskContinuationOptions.OnlyOnRanToCompletion | TaskContinuationOptions.LongRunning));

            case QualityOfService.AtMostOnce:
            case QualityOfService.ExactlyOnce:
                var tcs = new TaskCompletionSource <MqttCommand>();
                tcs.SetException(new ProtocolException(msg.CommandMessage));
                return(tcs.Task);

            default:
                throw new InvalidOperationException("Unknown QoS");
            }
        }
示例#8
0
文件: Program.cs 项目: hezlog/MQTT
        private static void c_OnUnsolicitedMessage(object sender, ClientCommandEventArgs e)
        {
            MqttCommand command = e.Command;

            var p = command as Publish;

            if (p != null)
            {
                var sb = new StringBuilder();
                if (p.Header.Duplicate)
                {
                    sb.Append("!!! DUPLICATE !!! - ");
                }
                sb.AppendFormat("TOPIC: {0}", p.Topic);
                sb.AppendLine();
                foreach (char c in Encoding.ASCII.GetChars(p.Message))
                {
                    if (!char.IsControl(c))
                    {
                        sb.Append(c);
                    }
                }

                sb.AppendLine();
                var result = sb.ToString();

                lock (conLock)
                {
                    Console.WriteLine(result);
                }
            }
        }
示例#9
0
        internal Task <MqttCommand> WaitForCommand(CommandMessage message, MessageId messageId, TimeSpan timeout)
        {
            lock (_desireLock)
            {
                MqttCommand maybeLoved = _unlovedCommands.Where(c => c.MessageId == messageId && c.CommandMessage == message).FirstOrDefault();

                if (maybeLoved != null)
                {
                    var tcs = new TaskCompletionSource <MqttCommand>();
                    tcs.SetResult(maybeLoved);
                    return(tcs.Task);
                }
                else
                {
                    MqttCommand      result = null;
                    ManualResetEvent wait   = new ManualResetEvent(false);

                    Desire d = new Desire(message, messageId, (MqttCommand cmd) =>
                    {
                        result = cmd;
                        wait.Set();
                    });

                    _desireCache.AddAndRemoveDuplicates(d);

                    return(Task <MqttCommand> .Factory.StartNew(() =>
                    {
                        wait.WaitOne(timeout);
                        return result;
                    }));
                }
            }
        }
示例#10
0
        Task ICommandWriter.Send(NetworkConnection connection, MqttCommand command)
        {
            Debug.WriteLine("{0} : Writing command {1} id {2}", DateTime.Now.ToString("o"), command.CommandMessage, command.MessageId);

            byte[] bytes = command.ToByteArray();
            return(connection.Write(bytes, 0, bytes.Length));
        }
示例#11
0
        void ICommandWriter.Send(NetworkConnection connection, MqttCommand command)
        {
            byte[] bytes = command.ToByteArray();

            System.Diagnostics.Debug.WriteLine("SEND {0} => {1}", command, BitConverter.ToString(bytes).Replace("-", " "));

            connection.Stream.Write(bytes, 0, bytes.Length);
        }
示例#12
0
        MqttCommand ICommandReader.Read(NetworkConnection connection)
        {
            var header = FixedHeader.Load(connection);

            byte[] data = connection.ReadBytesOrFailAsync(header.RemainingLength).Await().Result;

            return(MqttCommand.Create(header, data));
        }
示例#13
0
文件: Client.cs 项目: hezlog/MQTT
        private void Notify(MqttCommand command)
        {
            UnsolicitedMessageCallback callback = OnUnsolicitedMessage;

            if (callback != null)
            {
                callback(this, new ClientCommandEventArgs(command));
            }
        }
示例#14
0
 private void QueueReadCommand(NamedConnection connection)
 {
     lock (_lock)
     {
         _runningCommands.Add(Task.Factory.StartNew <CommandRead>(() =>
         {
             ICommandReader reader = new CommandReader();
             MqttCommand cmd       = reader.Read(connection.Connection);
             return(new CommandRead(cmd, connection));
         }, TaskCreationOptions.LongRunning));
     }
 }
示例#15
0
        public override Task Start(MqttCommand command, Action <MqttCommand> onSuccess)
        {
            if (onSuccess == null)
            {
                onSuccess = c => { };
            }

            return(Send(new ConnAck())
                   .ContinueWith(task =>
                                 onSuccess(command),
                                 TaskContinuationOptions.OnlyOnRanToCompletion | TaskContinuationOptions.LongRunning));
        }
示例#16
0
        internal Task Deliver(MqttCommand cmd)
        {
            switch (cmd.CommandMessage)
            {
            case CommandMessage.PUBLISH:
                return(StartNew(new PublishReceive(cmd, this)));

            case CommandMessage.SUBSCRIBE:
                return(StartNew(new SubscribeReceive(cmd, this)));

            case CommandMessage.PINGREQ:
                return(StartNew(new PingReceived(cmd, this)));

            case CommandMessage.DISCONNECT:
                return(StartNew(new DisconnectReceived(cmd, this)));

            case CommandMessage.UNSUBSCRIBE:
                return(StartNew(new UnsubscribeReceived(cmd, this)));

            case CommandMessage.PUBACK:
            case CommandMessage.PUBCOMP:
            case CommandMessage.PUBREC:
            case CommandMessage.PUBREL:
                var tcsRan = new TaskCompletionSource <object>();
                try
                {
                    lock (_lock)
                    {
                        Action <MqttCommand> toRun;
                        if (_desires.TryRemove(cmd.MessageId.Value, out toRun))
                        {
                            toRun(cmd);
                        }
                    }

                    tcsRan.SetResult(null);
                }
                catch (Exception ex)
                {
                    tcsRan.SetException(ex);
                }
                return(tcsRan.Task);

            default:
                var tcsEx = new TaskCompletionSource <object>();
                tcsEx.SetException(new InvalidOperationException("Nope!"));
                return(tcsEx.Task);
            }
        }
示例#17
0
        public override Task Start(MqttCommand command, Action <MqttCommand> onSuccess)
        {
            if (onSuccess == null)
            {
                onSuccess = c => { };
            }

            return(Send(command)
                   .ContinueWith(task =>
                                 WaitFor(CommandMessage.CONNACK, MessageId.Any, TimeSpan.FromSeconds(30)),
                                 TaskContinuationOptions.OnlyOnRanToCompletion | TaskContinuationOptions.LongRunning)
                   .ContinueWith(task =>
                                 onSuccess(command),
                                 TaskContinuationOptions.OnlyOnRanToCompletion | TaskContinuationOptions.LongRunning));
        }
示例#18
0
        private Task ProcessSubscription(MqttCommand msg, Action <MqttCommand> release)
        {
            SubAck    ack    = new SubAck(msg.MessageId);
            Subscribe subCmd = msg as Subscribe;

            foreach (Subscription sub in subCmd.Subscriptions)
            {
                ack.Grants.Add(QualityOfService.AtMostOnce);
            }

            return(Send(ack)
                   .ContinueWith((task) =>
                                 Task.Factory.StartNew(() => release(msg)),
                                 TaskContinuationOptions.OnlyOnRanToCompletion | TaskContinuationOptions.LongRunning));
        }
示例#19
0
        internal NamedConnection Run(NetworkConnection connection)
        {
            MqttCommand command = _reader.Read(connection);

            if (command.CommandMessage != Types.CommandMessage.CONNECT)
            {
                throw new ProtocolException(command.CommandMessage, "Expected CONNECT");
            }

            Connect connect = (Connect)command;

            _writer.Send(connection, new ConnAck());

            return(new NamedConnection(connect.ClientIdentifier, connection));
        }
示例#20
0
        public Task Send(MqttCommand command)
        {
            var tcs = new TaskCompletionSource <object>();

            try
            {
                _writer.Send(_connection, command);
                tcs.SetResult(null);
            }
            catch (Exception ex)
            {
                tcs.SetException(ex);
            }

            return(tcs.Task);
        }
示例#21
0
        public Task Send(MqttCommand command)
        {
            var tcs = new TaskCompletionSource <object>();

            try
            {
                EnqueueResponse(command);
                tcs.SetResult(null);
            }
            catch (Exception ex)
            {
                tcs.SetException(ex);
            }

            return(tcs.Task);
        }
示例#22
0
        public void Deliver(MqttCommand command)
        {
            lock (_desireLock)
            {
                Desire desire;

                if (_desireCache.TryGetAndRemove(command.CommandMessage, command.MessageId, out desire))
                {
                    desire.Fulfilled(command);
                }
                else
                {
                    _unlovedCommands.Add(command);
                }
            }
        }
示例#23
0
        void c_OnUnsolicitedMessage(object sender, ClientCommandEventArgs e)
        {
            System.Windows.Deployment.Current.Dispatcher.BeginInvoke(() =>
            {
                if (nextUpdate > DateTime.UtcNow)
                {
                    return;
                }

                nextUpdate = DateTime.UtcNow.AddSeconds(1);

                MqttCommand command = e.Command;

                Publish p = command as Publish;
                if (p != null)
                {
                    lock (this.textBlock1)
                    {
                        if (p.Header.Duplicate)
                        {
                            this.textBlock1.Text = "!!! DUPLICATE !!! - ";
                        }

                        StringBuilder sb = new StringBuilder();

                        sb.AppendFormat("TOPIC: {0}", p.Topic);
                        sb.AppendLine();
                        sb.AppendLine();

                        foreach (char c in UTF8Encoding.UTF8.GetChars(p.Message))
                        {
                            if (!char.IsControl(c))
                            {
                                sb.Append(c);
                            }
                        }


                        sb.AppendLine();
                        sb.AppendLine();

                        this.textBlock1.Text = sb.ToString();
                    }
                }
            });
        }
示例#24
0
        MqttCommand ICommandReader.Read(NetworkConnection connection)
        {
            byte[] data = null;

            FixedHeader header = FixedHeader.Load(connection);

            if (header.RemainingLength > 0)
            {
                data = connection.Stream.ReadBytesOrFailAsync(header.RemainingLength).Await().Result;
            }

            MqttCommand cmd = MqttCommand.Create(header, data);

            System.Diagnostics.Debug.WriteLine("RECV {0}", cmd);

            return(cmd);
        }
示例#25
0
        internal void Complete(MqttCommand command)
        {
            switch (command.CommandMessage)
            {
            case CommandMessage.SUBSCRIBE:
                var sub = command as Subscribe;
                if (sub == null)
                {
                    throw new ArgumentException("Message declared itself as Subscribe but was not of type Subscribe", "command");
                }
                ActiveSubscriptions.Current.Add(ClientId, sub.Subscriptions);
                break;

            case CommandMessage.PUBLISH:
                var pub = command as Publish;
                if (pub == null)
                {
                    throw new ArgumentException("Message declared itself as Publish but was not of type Publish", "command");
                }
                foreach (var client in ActiveSubscriptions.Current.Publish(ClientId, pub.Topic, pub.Message))
                {
                    Manager.Send(client, new Publish(pub.Topic, pub.Message));
                }
                break;

            case CommandMessage.UNSUBSCRIBE:
                var unsub = command as Unsubscribe;
                if (unsub == null)
                {
                    throw new ArgumentException("Message declared itself as Unsubscribe but was not of type Unsubscribe", "command");
                }
                ActiveSubscriptions.Current.Remove(ClientId, unsub.Topics);
                break;

            case CommandMessage.PINGREQ:
                Send(new PingReq());
                break;

            case CommandMessage.DISCONNECT:
                ActiveSubscriptions.Current.Remove(ClientId);
                Connection.Disconnect();
                Manager.Disconnect(this);
                break;
            }
        }
示例#26
0
        public override Task Start(MqttCommand command, Action <MqttCommand> onSuccess)
        {
            if (onSuccess == null)
            {
                onSuccess = p => { };
            }

            switch (command.Header.QualityOfService)
            {
            case QualityOfService.AtMostOnce:
                return(Send(command)
                       .ContinueWith(task =>
                                     onSuccess(command),
                                     TaskContinuationOptions.OnlyOnRanToCompletion | TaskContinuationOptions.LongRunning));

            case QualityOfService.AtLeastOnce:
                return(Send(command)
                       .ContinueWith(task =>
                                     WaitFor(CommandMessage.PUBACK, command.MessageId, TimeSpan.FromSeconds(60)),
                                     TaskContinuationOptions.OnlyOnRanToCompletion | TaskContinuationOptions.LongRunning)
                       .ContinueWith(task =>
                                     onSuccess(command),
                                     TaskContinuationOptions.OnlyOnRanToCompletion | TaskContinuationOptions.LongRunning));

            case QualityOfService.ExactlyOnce:
                return(Send(command)
                       .ContinueWith(task =>
                                     WaitFor(CommandMessage.PUBREC, command.MessageId, TimeSpan.FromSeconds(60)),
                                     TaskContinuationOptions.OnlyOnRanToCompletion | TaskContinuationOptions.LongRunning)
                       .ContinueWith(task =>
                                     Send(new PubRel(command.MessageId)),
                                     TaskContinuationOptions.OnlyOnRanToCompletion | TaskContinuationOptions.LongRunning)
                       .ContinueWith(task =>
                                     WaitFor(CommandMessage.PUBCOMP, command.MessageId, TimeSpan.FromSeconds(60)),
                                     TaskContinuationOptions.OnlyOnRanToCompletion | TaskContinuationOptions.LongRunning)
                       .ContinueWith(task =>
                                     onSuccess(command),
                                     TaskContinuationOptions.OnlyOnRanToCompletion | TaskContinuationOptions.LongRunning));

            default:
                throw new InvalidOperationException("Unknown QoS");
            }
        }
示例#27
0
        private Task ProcessSubscription(MqttCommand msg, Action <MqttCommand> release)
        {
            var ack    = new SubAck(msg.MessageId);
            var subCmd = msg as Subscribe;

            if (subCmd == null)
            {
                throw new InvalidOperationException("Subscribe operationg expects Subscribe command");
            }

            foreach (Subscription sub in subCmd.Subscriptions)
            {
                ack.Grants.Add(QualityOfService.AtMostOnce);
            }

            return(Send(ack)
                   .ContinueWith(task =>
                                 Task.Factory.StartNew(() => release(msg)),
                                 TaskContinuationOptions.OnlyOnRanToCompletion | TaskContinuationOptions.LongRunning));
        }
示例#28
0
        public override Task Start(MqttCommand msg, Action <MqttCommand> release)
        {
            if (release == null)
            {
                release = p => { };
            }

            switch (msg.Header.QualityOfService)
            {
            case QualityOfService.AtLeastOnce:
                return(ProcessSubscription(msg, release));

            case QualityOfService.AtMostOnce:
            case QualityOfService.ExactlyOnce:
                var tcs = new TaskCompletionSource <MqttCommand>();
                tcs.SetException(new ProtocolException(msg.CommandMessage));
                return(tcs.Task);

            default:
                throw new InvalidOperationException("Unknown QoS");
            }
        }
示例#29
0
        private void ReceiveLoop(Action <MqttCommand> recv)
        {
            try
            {
                while (true)
                {
                    MqttCommand command = ReadCommand();

                    if (recv != null)
                    {
                        recv(command);
                    }
                }
            }
            catch (Exception ex)
            {
                if (_connection.Connected)
                {
                    _connection.Disconnect();
                }
                // swallow and let the thread die naturally
            }
        }
示例#30
0
        private void ReceiveLoop(Action <MqttCommand> recv)
        {
            try
            {
                while (true)
                {
                    MqttCommand command = ReadCommand();

                    if (recv != null)
                    {
                        recv(command);
                    }
                }
            }
            catch (Exception ex)
            {
                if (_connection.Connected)
                {
                    _connection.Disconnect();
                }

                NotifyOfDisconnect(_connection, ex);
            }
        }