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"); } }
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(); } }
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; } }
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; } }
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; } }
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); } }
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"); } }
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); } } }
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; })); } } }
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)); }
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); }
MqttCommand ICommandReader.Read(NetworkConnection connection) { var header = FixedHeader.Load(connection); byte[] data = connection.ReadBytesOrFailAsync(header.RemainingLength).Await().Result; return(MqttCommand.Create(header, data)); }
private void Notify(MqttCommand command) { UnsolicitedMessageCallback callback = OnUnsolicitedMessage; if (callback != null) { callback(this, new ClientCommandEventArgs(command)); } }
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)); } }
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)); }
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); } }
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)); }
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)); }
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)); }
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); }
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); }
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); } } }
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(); } } }); }
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); }
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; } }
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"); } }
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)); }
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"); } }
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 } }
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); } }