public override void Evaluate(int spreadMax) { base.Evaluate(spreadMax); if ((FClient != null) && FClient.IsConnected) { HashSet <Tuple <string, QOS> > currentSubscriptions = new HashSet <Tuple <string, QOS> >(); List <Tuple <string, QOS> > newSubscriptions = new List <Tuple <string, QOS> >(); for (int i = 0; i < spreadMax; i++) { #region sending if (FInSend[i]) { if (FInTopic[i].Contains("/#") || FInTopic[i].Contains("/*")) { FMessageStatusQueue.Enqueue("Topic at slice " + i.ToString() + " contains illegal characters for publishing"); } else { var packetId = FClient.Publish(FInTopic[i], UTF8Enc.GetBytes(FInMessage[i]), (byte)FInQoS[i], FInRetained[i]); FPublishStatus.Add(packetId); } } if (FInRemoveRetained[i]) { FClient.Publish(FInTopic[i], new byte[] { }, (byte)0, true); } #endregion sending //subscription and unsubscription has to be handled outside this loop //unsubscription has to be triggered first (matters in the case of same topic with different qos) #region receiving if (FInReceive[i]) { var tup = new Tuple <string, QOS>(FInTopic[i], FInQoS[i]); currentSubscriptions.Add(tup); if (!FSubscriptions.Remove(tup)) { newSubscriptions.Add(tup); } } #endregion receiving } #region unsubscribe try { if (FSubscriptions.Count > 0) { foreach (var tuple in FSubscriptions) { var unsubscribeId = FClient.Unsubscribe(new string[] { tuple.Item1 }); FUnsubscribeStatus.Add(unsubscribeId, tuple); } } FSubscriptions = new HashSet <Tuple <string, QOS> >(currentSubscriptions); } catch (Exception e) { FLogger.Log(e); foreach (var s in currentSubscriptions) { FSubscriptions.Add(s); } } #endregion unsubscribe #region subscribe if (FNewSession) { newSubscriptions.AddRange(FSubscriptions); FNewSession = false; } foreach (var subs in newSubscriptions) { try { var subscribeId = FClient.Subscribe(new string[] { subs.Item1 }, new byte[] { (byte)subs.Item2 }); FSubscribeStatus.Add(subscribeId, subs); } catch { FLogger.Log(LogType.Warning, string.Format("couldn't subscribe to {0} with qos {1}", subs.Item1, subs.Item2)); } } #endregion subscribe } if (FMessageStatusQueue.Count > 0) { FOutMessageStatus.AssignFrom(FMessageStatusQueue.ToArray()); FMessageStatusQueue.Clear(); } FOutTopic.AssignFrom(FPacketQueue.Select(x => x.Topic).ToArray()); FOutMessage.AssignFrom(FPacketQueue.Select(x => UTF8Enc.GetString(x.Message))); FOutQoS.AssignFrom(FPacketQueue.Select(x => (QOS)x.QosLevel)); FOutIsRetained.AssignFrom(FPacketQueue.Select(x => x.Retain)); FOutOnData[0] = FPacketQueue.Count > 0; FPacketQueue.Clear(); FOutboundCount[0] = FPublishStatus.Count; }