Example #1
0
        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;
        }