Changeset 1068


Ignore:
Timestamp:
Jan 12, 2010, 11:57:12 AM (12 years ago)
Author:
arnold
Message:

Vulminous changes and updates (for example: enabling replacement of the publisher, WPF QuickWatchPresentation in P2PManager, etc.)

Location:
trunk/CrypPlugins
Files:
15 edited

Legend:

Unmodified
Added
Removed
  • trunk/CrypPlugins/PeerToPeerManager/P2PManager.cs

    r1012 r1068  
    2525using System.ComponentModel;
    2626using KeySearcher;
    27 
    28 /*
    29  * TODO:
    30  * - derzeit dasselbe wie PUBLISHER - umformen zum Manager!!! (arbeitsteilung)
    31  */
     27using System.Windows.Controls;
     28using System.Windows.Threading;
    3229
    3330namespace Cryptool.Plugins.PeerToPeer
     
    133130        }
    134131
    135         private string sOutputvalue;
    136         [PropertyInfo(Direction.OutputData, "Managing Information", "Displays all distribution information", "", true, false, DisplayLevel.Beginner, QuickWatchFormat.Text, null)]
    137         public string Outputvalue
    138         {
    139             get
    140             {
    141                 return this.sOutputvalue;
    142             }
    143             set
    144             {
    145                 this.sOutputvalue = value;
    146                 OnPropertyChanged("Outputvalue");
    147             }
    148         }
    149 
    150132        #endregion
    151133
     
    168150            this.settings.TaskPaneAttributeChanged += new TaskPaneAttributeChangedHandler(settings_TaskPaneAttributeChanged);
    169151            this.settings.OnPluginStatusChanged += new StatusChangedEventHandler(settings_OnPluginStatusChanged);
    170         }
     152
     153            QuickWatchPresentation = new P2PManagerQuickWatch();
     154        }
     155
     156        #region QuickWatchPresentation Stuff
     157
     158        public UserControl QuickWatchPresentation
     159        {
     160            get;
     161            private set;
     162        }
     163
     164        public UserControl Presentation
     165        {
     166            get { return QuickWatchPresentation; }
     167        }
     168
     169        private void UpdateQuickWatch(double progressInPercent)
     170        {
     171            UpdateQuickWatch(this.p2pManager.GetGlobalTop10List(), this.p2pManager.PatternAmount,
     172                this.p2pManager.PatternsInProcess, this.p2pManager.LeftPatterns,
     173                this.p2pManager.FinishedPatterns, progressInPercent, this.p2pManager.FreeWorkers, this.p2pManager.BusyWorkers);
     174        }
     175
     176        private void UpdateQuickWatch(LinkedList<KeySearcher.KeySearcher.ValueKey> globalTop10List,
     177            int jobsTotalAmount, int jobsInProgress, int jobsLeft, int jobsFinished, double progressInPercent,
     178            int freeWorkers, int busyWorkers)
     179        {
     180            System.Text.ASCIIEncoding enc = new System.Text.ASCIIEncoding();
     181            LinkedListNode<KeySearcher.KeySearcher.ValueKey> listNode;
     182
     183            if (QuickWatchPresentation.IsVisible)
     184            {
     185                ((P2PManagerQuickWatch)QuickWatchPresentation).Dispatcher.Invoke(DispatcherPriority.Normal, (SendOrPostCallback)delegate
     186                {
     187                    ((P2PManagerQuickWatch)QuickWatchPresentation).txtProgressInPercent.Text = Math.Round(progressInPercent, 2) + "%";
     188                    ((P2PManagerQuickWatch)QuickWatchPresentation).txtTotal.Text = "" + jobsTotalAmount;
     189                    ((P2PManagerQuickWatch)QuickWatchPresentation).txtInProgress.Text = "" + jobsInProgress;
     190                    ((P2PManagerQuickWatch)QuickWatchPresentation).txtLeft.Text = "" + jobsLeft;
     191                    ((P2PManagerQuickWatch)QuickWatchPresentation).txtFinished.Text = "" + jobsFinished;
     192
     193                    ((P2PManagerQuickWatch)QuickWatchPresentation).txtFreeWorker.Text = "" + freeWorkers;
     194                    ((P2PManagerQuickWatch)QuickWatchPresentation).txtBusyWorker.Text = "" + busyWorkers;
     195
     196                    ((P2PManagerQuickWatch)QuickWatchPresentation).entries.Clear();
     197                    listNode = globalTop10List.First;
     198
     199                    int i = 0;
     200                    while (listNode != null)
     201                    {
     202                        i++;
     203
     204                        ResultEntry entry = new ResultEntry();
     205                        entry.Ranking = "" + i;
     206                        entry.Value = "" + Math.Round(listNode.Value.value, 3);
     207                        entry.Key = listNode.Value.key;
     208                        entry.Text = enc.GetString(listNode.Value.decryption);
     209
     210                        ((P2PManagerQuickWatch)QuickWatchPresentation).entries.Add(entry);
     211                        listNode = listNode.Next;
     212                    }
     213                }, null);
     214            }
     215        }
     216
     217        #endregion
    171218
    172219        void settings_OnPluginStatusChanged(IPlugin sender, StatusEventArgs args)
     
    221268        }
    222269
    223         public System.Windows.Controls.UserControl Presentation
    224         {
    225             get { return null; }
    226         }
    227 
    228         public System.Windows.Controls.UserControl QuickWatchPresentation
    229         {
    230             get { return null; }
    231         }
    232270        // Pre-Execute Method is below this region
    233271
     
    280318                this.p2pManager.OnFinishedDistributingPatterns += new P2PManagerBase.FinishedDistributingPatterns(p2pManager_OnFinishedDistributingPatterns);
    281319                this.p2pManager.OnProcessProgress += new P2PManagerBase.ProcessProgress(p2pManager_OnProcessProgress);
    282                 //this.p2pManager.Start(this.settings.TopicName, (long)this.settings.SendAliveMessageInterval);
    283320            }
    284321        }
     
    287324        {
    288325            ProgressChanged(progressInPercent, 100.0);
    289         }
    290 
    291         void p2pManager_OnFinishedOnePattern(string wildCardKey, double firstCoeffResult, string firstKeyResult, string workerId)
    292         {
    293             if (this.Outputvalue != null)
    294                 this.Outputvalue += "\n";
    295             this.Outputvalue += "Value: " + firstCoeffResult.ToString() + "\nKey: " + firstKeyResult + "\nFrom: " + workerId;
     326            UpdateQuickWatch(progressInPercent);
     327        }
     328
     329        void p2pManager_OnFinishedOnePattern(string wildCardKey, double firstCoeffResult, string firstKeyResult, PeerId workerId)
     330        {
    296331        }
    297332
     
    299334        {
    300335            this.settings.MngStatusChanged(P2PManagerSettings.MngStatus.Finished);
    301 
    302             this.Outputvalue = this.p2pManager.GetGlobalTopList(lstTopList);
    303 
    304             //this.Outputvalue = "All Patterns were bruteforced:";
    305336        }
    306337
     
    348379                    kp.WildcardKey = "30-30-30-30-30-30-30-30-30-30-30-30-30-**-**-**";
    349380                else if (len == 135) //DES
    350                     kp.WildcardKey = "30-30-30-**-**-**-**-**";
     381                    kp.WildcardKey = "30-30-30-30-**-**-**-**";
    351382                else
    352383                    throw (new Exception("Encryption Type not supported"));
     
    354385            }
    355386
    356             //this.p2pManager.StartManager(this.settings.TopicName, (long)this.settings.SendAliveMessageInterval, kp);
    357387            this.p2pManager.StartManager(this.settings.TopicName, (long)this.settings.SendAliveMessageInterval, kp, this.settings.KeyPatternSize);
    358388
  • trunk/CrypPlugins/PeerToPeerManager/P2PManagerBase.cs

    r1012 r1068  
    1010using System.IO;
    1111using System.Threading;
     12using Cryptool.PluginBase.IO;
    1213
    1314/*bearbeitung
    1415 * TODO:
    1516 * - Order the results when they arrived as a message! (MessageReceived method)
    16  * - Fire event, when all Pattern were distributed and ALL there results had arrived
    1717 */
    1818
     
    2929        public event FinishedDistributingPatterns OnFinishedDistributingPatterns;
    3030
    31         public delegate void FinishedOnePattern(string wildCardKey, double firstCoeffResult, string firstKeyResult, string workerId);
     31        public delegate void FinishedOnePattern(string wildCardKey, double firstCoeffResult, string firstKeyResult, PeerId worker);
    3232        /// <summary>
    3333        /// Will be thrown when ONE pattern is bruteforced successfully
     
    4343
    4444        private const int MAX_IN_TOP_LIST = 10;
     45        private const string DHT_ENCRYPTED_TEXT = "EncryptedText";
     46        private const string DHT_INIT_VECTOR = "InitializationVector";
    4547
    4648        private bool managerStarted = false;
     
    8082        /// Key = PeerId, Value = Pattern (key space of key pattern)
    8183        /// </summary>
    82         Dictionary<string, KeyPattern> allocatedPatterns;
     84        Dictionary<PeerId, KeyPattern> allocatedPatterns;
    8385        /// <summary>
    8486        /// Key = KeyPattern (key space), Value = Result
    8587        /// </summary>
    86         Dictionary<KeyPattern, string> patternResults;
     88        Dictionary<KeyPattern, LinkedList<KeySearcher.KeySearcher.ValueKey>> patternResults;
    8789        /// <summary>
    8890        /// Global TopList, which will be actualized every time, when a new sub-result arrives. Consists only the top10 results.
     
    9698        {
    9799            this.leftKeyPatterns = new Queue<KeyPattern>();
    98             this.allocatedPatterns = new Dictionary<string, KeyPattern>();
    99             this.patternResults = new Dictionary<KeyPattern, string>();
     100            this.allocatedPatterns = new Dictionary<PeerId, KeyPattern>();
     101            this.patternResults = new Dictionary<KeyPattern, LinkedList<KeySearcher.KeySearcher.ValueKey>>();
    100102            this.globalTopList = getDummyTopList(MAX_IN_TOP_LIST);
    101103        }
    102104
    103         protected override void MessageReceived(PeerId sourceAddr, string sData)
    104         {
    105             PubSubMessageType msgType = this.p2pControl.GetMsgType(sData);
    106 
    107             if (msgType != PubSubMessageType.NULL)
    108             {
    109                 // ignore Solution case, because other worker could work on...
    110                 if (msgType != PubSubMessageType.Solution)
    111                     // base class handles all administration cases (register, alive, unregister, ping, pong, ...)
    112                     base.MessageReceived(sourceAddr, sData);
    113             }
    114             else
    115             {
    116                 ProcessPatternResult(sData, sourceAddr);
    117             }
    118         }
     105        protected override void p2pControl_OnPayloadMessageReceived(PeerId sender, byte[] data)
     106        {
     107            ProcessPatternResult(data, sender);
     108        }
     109
     110        protected override void p2pControl_OnSystemMessageReceived(PeerId sender, PubSubMessageType msgType)
     111        {
     112            // ignore Solution case, because other worker could work on...
     113            if (msgType != PubSubMessageType.Solution)
     114                // base class handles all administration cases (register, alive, unregister, ping, pong, ...)
     115                base.p2pControl_OnSystemMessageReceived(sender, msgType);
     116        }
     117
    119118
    120119        /// <summary>
     
    122121        /// actualize the Top-10-List of ALL results and sets the worker free again.
    123122        /// </summary>
    124         /// <param name="sPatternResult">serialized pattern result</param>
     123        /// <param name="patternResult">serialized pattern result</param>
    125124        /// <param name="workerId">ID of the actual worker</param>
    126125        /// <returns></returns>
    127         private bool ProcessPatternResult(string sPatternResult, PeerId workerId)
     126        private bool ProcessPatternResult(byte[] patternResult, PeerId workerId)
    128127        {
    129128            // if sending peer is in the allocatedPatterns Dict, its an (intermediate) result
    130             if (this.allocatedPatterns.ContainsKey(workerId.stringId))
    131             {
    132                 GuiLogging("Result from worker '" + workerId.stringId + "' received. Data: " + sPatternResult, NotificationLevel.Debug);
    133 
    134                 KeyPattern actualPattern = this.allocatedPatterns[workerId.stringId];
    135 
    136                 LinkedList<KeySearcher.KeySearcher.ValueKey> lstResults = DeserializeKeySearcherResult(sPatternResult);
     129            if (this.allocatedPatterns.ContainsKey(workerId))
     130            {
     131                GuiLogging("Result from worker '" + workerId + "' received. Data: " + UTF8Encoding.UTF8.GetString(patternResult,0,400), NotificationLevel.Debug);
     132
     133                KeyPattern actualPattern = this.allocatedPatterns[workerId];
     134
     135                KeySearcherResult keySearcherResult = new KeySearcherResult();
     136                LinkedList<KeySearcher.KeySearcher.ValueKey> lstResults = keySearcherResult.DeserializeResult(patternResult);
    137137
    138138                if (lstResults != null)
     
    140140                    KeySearcher.KeySearcher.ValueKey firstResult = lstResults.First<KeySearcher.KeySearcher.ValueKey>();
    141141
    142                     GuiLogging("Result was deserialized. Coeff.Value: " + firstResult.value.ToString() + ", Key: '" + firstResult.key + "'", NotificationLevel.Debug);
     142                    GuiLogging("Result was deserialized. First Value: " + firstResult.value.ToString() + ", Key: '" + firstResult.key + "'", NotificationLevel.Debug);
    143143
    144144                    // if patternResult already contains a result for this pattern, compare the results
     
    147147                    {
    148148                        // TODO: compare results and take the better one
    149                         this.patternResults[actualPattern] = sPatternResult;
     149                        this.patternResults[actualPattern] = lstResults;
    150150                        GuiLogging("New result for the same pattern (Value: " + firstResult.value.ToString() + ", Key: '" + firstResult.key + "') received. So it was updated.", NotificationLevel.Debug);
    151151                    }
    152152                    else
    153153                    {
    154                         this.patternResults.Add(actualPattern, sPatternResult);
     154                        this.patternResults.Add(actualPattern, lstResults);
    155155                        GuiLogging("Received FIRST result for the pattern (Value: " + firstResult.value.ToString() + ", Key: '" + firstResult.key + "')", NotificationLevel.Debug);
    156156                    }
    157                     // TODO: Compare, actualize and display top 10 list of all results received from the different workers
    158157                    ActualizeGlobalTopList(lstResults);
    159158
     
    162161                    // send information to the Plugin to display the first result
    163162                    if (OnFinishedOnePattern != null)
    164                         OnFinishedOnePattern(actualPattern.WildcardKey, firstResult.value, firstResult.key, workerId.stringId);
     163                        OnFinishedOnePattern(actualPattern.WildcardKey, firstResult.value, firstResult.key, workerId);
    165164
    166165                    //remove, because task is solved and stored in Dictionary patternResults
    167                     this.allocatedPatterns.Remove(workerId.stringId);
     166                    this.allocatedPatterns.Remove(workerId);
    168167                    // because result-sending worker is again free, set it to free sin the management, so it will get a new KeyPattern if available
    169168                    ((WorkersManagement)this.peerManagement).SetBusyWorkerToFree(workerId);
     
    171170                else
    172171                {
    173                     GuiLogging("Deserializing result canceled: '" + sPatternResult + "'.", NotificationLevel.Error);
     172                    GuiLogging("Deserializing result canceled: '" + UTF8Encoding.UTF8.GetString(patternResult) + "'.", NotificationLevel.Error);
    174173                }
    175174                if (this.leftKeyPatterns.Count == 0)
     
    178177                        OnFinishedDistributingPatterns(this.globalTopList);
    179178                }
     179                GetProgressInformation();
    180180
    181181                return true;
     
    183183            else
    184184            {
    185                 GuiLogging("Received Message from non-working peer. Data: " + sPatternResult + ", ID: " + workerId.stringId, NotificationLevel.Info);
     185                GuiLogging("Received Message from non-working peer. Data: " + UTF8Encoding.UTF8.GetString(patternResult) + ", ID: " + workerId, NotificationLevel.Info);
    186186            }
    187187            return false;
    188         }
    189 
    190         /* serialization information: 3 fields per data set in the following order:
    191          * 1) value (double)
    192          * 2) key (string)
    193          * 3) decryption (byte[]) */
    194         private string seperator = "#;#";
    195         private string dataSetSeperator = "|**|";
    196         private LinkedList<KeySearcher.KeySearcher.ValueKey> DeserializeKeySearcherResult(string sSerializedResult)
    197         {
    198             LinkedList<KeySearcher.KeySearcher.ValueKey> lstRet = new LinkedList<KeySearcher.KeySearcher.ValueKey>();
    199             string[] serveralDataSets = sSerializedResult.Split(dataSetSeperator.ToCharArray(),StringSplitOptions.RemoveEmptyEntries);
    200             for (int i = 0; i < serveralDataSets.Length; i++)
    201             {
    202                 string[] severalFieldsInDataSet = serveralDataSets[i].Split(seperator.ToCharArray(),StringSplitOptions.RemoveEmptyEntries);
    203                 if(severalFieldsInDataSet.Length != 3)
    204                     return null;
    205                 // build ValueKey from splitted string
    206                 KeySearcher.KeySearcher.ValueKey valKey = new KeySearcher.KeySearcher.ValueKey();
    207                 valKey.value = Convert.ToDouble(severalFieldsInDataSet[0]);
    208                 valKey.key = severalFieldsInDataSet[1];
    209                 valKey.decryption = UTF8Encoding.UTF8.GetBytes(severalFieldsInDataSet[2]);
    210                 // add builded ValueKey to list
    211                 lstRet.AddLast(valKey);
    212             }
    213             return lstRet;
    214188        }
    215189
     
    227201            else
    228202                GuiLogging("No more patterns left. So wait for the last results, than close this task.", NotificationLevel.Debug);
     203            GetProgressInformation();
    229204        }
    230205
    231206        private void peerManagement_OnSubscriberRemoved(PeerId peerId)
    232207        {
    233             if (this.allocatedPatterns.ContainsKey(peerId.stringId))
     208            if (this.allocatedPatterns.ContainsKey(peerId))
    234209            {
    235210                // because actual processing worker was removed, its job must be added to LeftKeyPatterns-List
    236                 this.leftKeyPatterns.Enqueue(this.allocatedPatterns[peerId.stringId]);
    237                 this.allocatedPatterns.Remove(peerId.stringId);
    238             }
    239             GuiLogging("REMOVED worker " + peerId.stringId, NotificationLevel.Info);
     211                this.leftKeyPatterns.Enqueue(this.allocatedPatterns[peerId]);
     212                bool removeResult = this.allocatedPatterns.Remove(peerId);
     213                GuiLogging("REMOVED worker with ID '" + peerId + "' and enqueue its pattern to the Pattern queue (" + removeResult + " ).", NotificationLevel.Info);
     214            }
     215            else
     216            {
     217                GuiLogging("REMOVED worker " + peerId, NotificationLevel.Info);
     218            }
     219            GetProgressInformation();
    240220        }
    241221
     
    252232                {
    253233                    KeyPattern actualKeyPattern = this.leftKeyPatterns.Dequeue();
    254                     this.allocatedPatterns.Add(subscriber.stringId, actualKeyPattern);
     234                    this.allocatedPatterns.Add(subscriber, actualKeyPattern);
    255235
    256236                    // send job (Keyspace) to the actual worker peer
    257                     this.p2pControl.SendToPeer(actualKeyPattern.SerializeToString(), subscriber.byteId);
    258 
    259                     GuiLogging("Pattern sent to peer (" + subscriber.stringId + "), Pattern: " + actualKeyPattern.WildcardKey, NotificationLevel.Debug);
     237                    this.p2pControl.SendToPeer(actualKeyPattern.Serialize(), subscriber);
     238
     239                    GuiLogging("Pattern sent to peer (" + subscriber + "), WildCardKey: " + actualKeyPattern.WildcardKey, NotificationLevel.Debug);
    260240
    261241                    // set free worker to busy in the peerManagement class
    262242                    ((WorkersManagement)this.peerManagement).SetFreeWorkerToBusy(subscriber);
    263243
    264                     GuiLogging("Worker was set to busy. (Id: " + subscriber.stringId + ")", NotificationLevel.Debug);
     244                    GuiLogging("Worker was set to busy. (Id: " + subscriber + ")", NotificationLevel.Debug);
    265245
    266246                    iCycle++;
     
    276256            } // end foreach
    277257
    278 
    279 
    280 
    281             GuiLogging("Bruteforcing progress: " + GetProgressInformation() + "%.", NotificationLevel.Debug);
    282 
    283 
     258            GetProgressInformation();
    284259
    285260            GuiLogging(iCycle.ToString() + " pattern(s) dispersed. Patterns left: " + this.leftKeyPatterns.Count.ToString(), NotificationLevel.Info);
     
    287262        }
    288263
     264        /// <summary>
     265        /// returns the percentual progress information of the whole job
     266        /// </summary>
     267        /// <returns>the percentual progress information of the whole job</returns>
    289268        private double GetProgressInformation()
    290269        {
    291             int leftPatterns = this.leftKeyPatterns.Count;
    292             int finishedPatterns = this.patternResults.Count;
    293             int patternsInProcess = this.allocatedPatterns.Count;
    294             int patternAmount = leftPatterns + finishedPatterns + patternsInProcess;
     270            double leftPatterns = this.leftKeyPatterns.Count;
     271            double finishedPatterns = this.patternResults.Count;
     272            double patternsInProcess = this.allocatedPatterns.Count;
     273            double patternAmount = leftPatterns + finishedPatterns + patternsInProcess;
    295274            double patternProgressInPercent;
    296275            if (finishedPatterns > 0 && patternsInProcess > 0)
    297                 patternProgressInPercent = 40 * (patternsInProcess / patternAmount) + 100 * (finishedPatterns / patternAmount);
     276                patternProgressInPercent = 30 * (patternsInProcess / patternAmount) + 100 * (finishedPatterns / patternAmount);
    298277            else if (patternsInProcess > 0)
    299                 patternProgressInPercent = 40 * (patternsInProcess / patternAmount);
     278                patternProgressInPercent = 30 * (patternsInProcess / patternAmount);
     279            else if (finishedPatterns > 0)
     280                patternProgressInPercent = 100 * (finishedPatterns / patternAmount);
    300281            else
    301282                patternProgressInPercent = 0.0;
     
    345326
    346327            GuiLogging("Begin building a KeyPatternPool with KeyPatternPartSize " + this.KeyPatternPartSize.ToString(), NotificationLevel.Debug);
    347             List<KeyPattern> arrKeyPatternPool = keyPattern.makeKeySearcherPool(this.KeyPatternPartSize);
    348             GuiLogging("Enqueue " + arrKeyPatternPool.Count + " KeyPattern-Parts to the JobList.", NotificationLevel.Debug);
    349             foreach (KeyPattern keyPatternPart in arrKeyPatternPool)
    350             {   
    351                 this.leftKeyPatterns.Enqueue(keyPatternPart);
     328
     329           
     330            /* TODO: Implement Stack instead of Queue later
     331             * At present: workaround this shit */
     332
     333            //List<KeyPattern> arrKeyPatternPool = keyPattern.makeKeySearcherPool(this.KeyPatternPartSize);
     334            //GuiLogging("Enqueue " + arrKeyPatternPool.Count + " KeyPattern-Parts to the JobList.", NotificationLevel.Debug);
     335            //foreach (KeyPattern keyPatternPart in arrKeyPatternPool)
     336            //{
     337            //    this.leftKeyPatterns.Enqueue(keyPatternPart);
     338            //}
     339
     340            Stack<KeyPattern> keyPatternPool = keyPattern.makeKeySearcherPool(this.keyPatternPartSize);
     341            GuiLogging("Enqueue " + keyPatternPool.Count + " KeyPattern-Parts to the JobList.", NotificationLevel.Debug);
     342            int keyCount = keyPatternPool.Count;
     343            for (int j = 0; j < keyCount; j++)
     344            {
     345                KeyPattern newPattern = keyPatternPool.Pop();
     346                if (newPattern != null)
     347                    this.leftKeyPatterns.Enqueue(newPattern);
     348                else
     349                    break;
    352350            }
    353351           
     
    366364            /* ************************************** */
    367365           
    368 
     366            /* TODO:
     367             * - Catch Encrypted CryptoolStream and InitVector from the ICryptControl
     368             * - store them in the DHT
     369            // store decrypted stream and initialization vector to DHT
     370            CryptoolStream encryptedStream;
     371            if(encryptedStream.CanRead)
     372            {
     373                byte[] encryptBuffer;
     374                int i = encryptedStream.Read(encryptBuffer,0,encryptedStream.Length-1);
     375                this.p2pControl.DHTstore(sTopic + DHT_ENCRYPTED_TEXT, );
     376            }
     377            */
    369378            this.ManagerStarted = true;
    370379
     380            GetProgressInformation();
     381
    371382            return bolStartResult;
    372            
    373383        }
    374384
     
    435445        }
    436446
    437         public string GetGlobalTopList(LinkedList<KeySearcher.KeySearcher.ValueKey> topList)
    438         {
    439             StringBuilder sbRet = new StringBuilder();
    440             LinkedListNode<KeySearcher.KeySearcher.ValueKey> node = topList.First;
    441             while (node != null)
    442             {
    443                 sbRet.AppendLine(node.Value.value.ToString());
    444                 sbRet.AppendLine(node.Value.key);
    445                 sbRet.AppendLine("-------------------");
    446                 node = node.Next;
    447             }
    448             return sbRet.ToString();
     447        #endregion
     448
     449        #region WPF-Display stuff
     450
     451        public LinkedList<KeySearcher.KeySearcher.ValueKey> GetGlobalTop10List()
     452        {
     453            return this.globalTopList;
     454        }
     455        public int LeftPatterns
     456        {
     457            get { return this.leftKeyPatterns.Count; }
     458        }
     459        public int FinishedPatterns
     460        {
     461            get { return this.patternResults.Count; }
     462        }
     463        public int PatternsInProcess
     464        {
     465            get { return this.allocatedPatterns.Count; }
     466        }
     467        public int PatternAmount
     468        {
     469            get { return LeftPatterns + FinishedPatterns + PatternsInProcess; }
     470        }
     471
     472        public int FreeWorkers
     473        {
     474            get { return ((WorkersManagement)this.peerManagement).GetFreeWorkersAmount();  }
     475        }
     476
     477        public int BusyWorkers
     478        {
     479            get { return ((WorkersManagement)this.peerManagement).GetBusyWorkersAmount(); }
    449480        }
    450481
  • trunk/CrypPlugins/PeerToPeerManager/P2PManagerSettings.cs

    r1012 r1068  
    8989        /* FOR TESTING ISSUES */
    9090
    91         private int sendAliveMessageInterval = 20;
     91        private int sendAliveMessageInterval = 60;
    9292        [TaskPane("Alive Message Interval (in seconds)","In which interval do you wish to receive Alive-Messages from your Subscribers?"
    9393            ,"Subscriber Properties",1,false,DisplayLevel.Beginner,ControlType.NumericUpDown, ValidationType.RangeInteger, 10, 3600)]
     
    126126        }
    127127
    128         private int keyPatternSize = 18; // in hundred-thousand
     128        private int keyPatternSize = 10; // in hundred-thousand
    129129        [TaskPane("KeyPatternSize", "Choose the Size of the specific sub-KeyPattern (in hundred-thousand steps)"
    130             , null, 3, false, DisplayLevel.Beginner, ControlType.NumericUpDown, ValidationType.RangeInteger, 15, 200)]
     130            , null, 3, false, DisplayLevel.Beginner, ControlType.NumericUpDown, ValidationType.RangeInteger, 1, 200)]
    131131        public int KeyPatternSize
    132132        {
  • trunk/CrypPlugins/PeerToPeerManager/PeerToPeerManager.csproj

    r980 r1068  
    5050    <Reference Include="System.Data" />
    5151    <Reference Include="System.Xml" />
     52    <Reference Include="UIAutomationProvider">
     53      <RequiredTargetFramework>3.0</RequiredTargetFramework>
     54    </Reference>
    5255    <Reference Include="WindowsBase">
    5356      <RequiredTargetFramework>3.0</RequiredTargetFramework>
     
    5861    <Compile Include="P2PManager.cs" />
    5962    <Compile Include="P2PManagerBase.cs" />
     63    <Compile Include="P2PManagerQuickWatch.xaml.cs">
     64      <DependentUpon>P2PManagerQuickWatch.xaml</DependentUpon>
     65    </Compile>
    6066    <Compile Include="P2PManagerSettings.cs" />
    6167    <Compile Include="Properties\AssemblyInfo.cs" />
     
    8591    <Resource Include="manager_medium_working.png" />
    8692  </ItemGroup>
     93  <ItemGroup>
     94    <Page Include="P2PManagerQuickWatch.xaml">
     95      <SubType>Designer</SubType>
     96      <Generator>MSBuild:Compile</Generator>
     97    </Page>
     98  </ItemGroup>
    8799  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
    88100  <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
  • trunk/CrypPlugins/PeerToPeerManager/WorkersManagement.cs

    r980 r1068  
    2121        public event FreeWorkersAvailable OnFreeWorkersAvailable;
    2222
    23         private Dictionary<string,PeerId> freeWorkers;
    24         private Dictionary<string,PeerId> busyWorkers;
     23        private HashSet<PeerId> freeWorkers;
     24        private HashSet<PeerId> busyWorkers;
    2525
    2626        #region own methods
     
    2828        public WorkersManagement(long expirationTime) : base(expirationTime)
    2929        {
    30             freeWorkers = new Dictionary<string,PeerId>();
    31             busyWorkers = new Dictionary<string,PeerId>();
     30            freeWorkers = new HashSet<PeerId>();
     31            busyWorkers = new HashSet<PeerId>();
    3232        }
    3333
    3434        public List<PeerId> GetFreeWorkers()
    3535        {
    36             return this.freeWorkers.Values.ToList<PeerId>();
     36            return this.freeWorkers.ToList<PeerId>();
    3737        }
    3838
    3939        public List<PeerId> GetBusyWorkers()
    4040        {
    41             return this.busyWorkers.Values.ToList<PeerId>();
     41            return this.busyWorkers.ToList<PeerId>();
    4242        }
    4343
     
    4949        public bool SetFreeWorkerToBusy(PeerId worker)
    5050        {
    51             if(this.busyWorkers.ContainsKey(worker.stringId))
    52                 return false;
    53 
    54             if (this.freeWorkers.ContainsKey(worker.stringId))
     51            bool ret = false;
     52            lock (this.freeWorkers)
    5553            {
    56                 lock(this.freeWorkers)
     54                if (!this.busyWorkers.Contains(worker) && this.freeWorkers.Contains(worker))
    5755                {
    58                     this.busyWorkers.Add(worker.stringId, worker);
    59                     this.freeWorkers.Remove(worker.stringId);
     56                    this.busyWorkers.Add(worker);
     57                    this.freeWorkers.Remove(worker);
     58                    ret = true;
    6059                }
    6160            }
    62             else
    63             {
    64                 return false;
    65             }
    66             return true;
     61            return ret;
    6762        }
    6863
     
    7469        public bool SetBusyWorkerToFree(PeerId worker)
    7570        {
    76             if (this.freeWorkers.ContainsKey(worker.stringId))
    77                 return false;
    78 
    79             if (this.busyWorkers.ContainsKey(worker.stringId))
     71            bool ret = false;
     72            lock (this.freeWorkers)
    8073            {
    81                 lock (this.freeWorkers)
     74                if (!this.freeWorkers.Contains(worker) && this.busyWorkers.Contains(worker))
    8275                {
    83                     this.freeWorkers.Add(worker.stringId, worker);
    84                     this.busyWorkers.Remove(worker.stringId);
     76                    this.freeWorkers.Add(worker);
     77                    this.busyWorkers.Remove(worker);
     78                    CheckAvailabilityOfFreeWorkers();
     79                    ret = true;
    8580                }
    86                 CheckAvailabilityOfFreeWorkers();
    8781            }
    88             else
    89             {
    90                 return false;
    91             }
    92             return true;
     82            return ret;
    9383        }
    9484
     
    9686        private void RemoveWorker(PeerId workerId)
    9787        {
    98             if (this.freeWorkers.ContainsKey(workerId.stringId))
    99                 this.freeWorkers.Remove(workerId.stringId);
     88            lock(this.freeWorkers)
     89            {
     90                if (this.freeWorkers.Contains(workerId))
     91                    this.freeWorkers.Remove(workerId);
    10092
    101             if (this.busyWorkers.ContainsKey(workerId.stringId))
    102             {
    103                 this.busyWorkers.Remove(workerId.stringId);
     93                if (this.busyWorkers.Contains(workerId))
     94                    this.busyWorkers.Remove(workerId);
    10495            }
    10596        }
     
    125116            bool bolBaseAdd = base.Add(subscriberId);
    126117
    127             // additional: fill freeWorker-List with new Worker
    128             if(!this.freeWorkers.ContainsKey(subscriberId.stringId))
    129                 this.freeWorkers.Add(subscriberId.stringId,subscriberId);
     118            // fill freeWorker-List with new Worker too
     119            if(!this.freeWorkers.Contains(subscriberId))
     120                this.freeWorkers.Add(subscriberId);
    130121
    131122            CheckAvailabilityOfFreeWorkers();
     
    173164                return base.ToString();
    174165        }
     166
     167        public int GetFreeWorkersAmount()
     168        {
     169            return this.freeWorkers.Count();
     170        }
     171
     172        public int GetBusyWorkersAmount()
     173        {
     174            return this.busyWorkers.Count();
     175        }
    175176    }
    176177}
  • trunk/CrypPlugins/PeerToPeerPublisher/P2PPublisher.cs

    r872 r1068  
    5454        private void settings_PropertyChanged(object sender, PropertyChangedEventArgs e)
    5555        {
     56            if (this.p2pPublisher == null || !this.p2pPublisher.Started)
     57                return;
     58
     59
    5660            // storing settings for subscribers in the DHT, so they can load them there
    5761            if (e.PropertyName == "SendAliveMessageInterval")
    5862            {
    59                 this.p2pControl.DHTstore(settings.TopicName + "Settings",
     63                this.p2pControl.DHTstore(settings.TopicName + "AliveMsg",
    6064                    System.BitConverter.GetBytes(this.settings.SendAliveMessageInterval * 1000));
    6165            }
     
    184188                this.p2pPublisher.Start(this.settings.TopicName, (long)this.settings.SendAliveMessageInterval);
    185189            }
     190            if (this.p2pPublisher != null && !this.p2pPublisher.Started) // when Workspace has stopped and has been started again
     191            {
     192                this.p2pPublisher.Start(this.settings.TopicName, (long)this.settings.SendAliveMessageInterval);
     193            }
    186194        }
    187195
  • trunk/CrypPlugins/PeerToPeerPublisher/P2PPublisherBase.cs

    r1022 r1068  
    99/*
    1010 * TODO:
    11  * - Removing excluded in Stop-Method, because it throws an exception... --> to be fixed by M.Helling (PAP)
    1211 * - FUTURE: dual data management of subscriber list (on local peer and in DHT)
    1312 */
     
    2221        #region Variables
    2322
     23        private const string DHT_ALIVE_POSTFIX = "AliveMsg";
     24
    2425        protected IP2PControl p2pControl;
    2526        protected SubscriberManagement peerManagement;
    2627        private string topic = String.Empty;
    27         private string sDHTSettingsPostfix = "Settings";       
    2828        private Timer timerWaitingForAliveMsg;
    2929        private PeerId ownPeerId;
     
    4545        {
    4646            this.p2pControl = p2pControl;
    47             this.p2pControl.OnPeerReceivedMsg +=new P2PBase.P2PMessageReceived(MessageReceived);
    4847        }
    4948
     
    6463        public bool Start(string sTopic, long aliveMessageInterval)
    6564        {
     65            this.p2pControl.OnPayloadMessageReceived += new P2PPayloadMessageReceived(p2pControl_OnPayloadMessageReceived);
     66            this.p2pControl.OnSystemMessageReceived += new P2PSystemMessageReceived(p2pControl_OnSystemMessageReceived);
     67
    6668            /* BEGIN: CHECKING WHETHER THERE HAS ALREADY EXIST ANOTHER PUBLISHER */
    6769            this.topic = sTopic;
     
    9395
    9496            bool bolTopicStored = this.p2pControl.DHTstore(sTopic, myPeerId.ToByteArray());
    95             bool bolSettingsStored = this.p2pControl.DHTstore(sTopic + this.sDHTSettingsPostfix,
     97            bool bolSettingsStored = this.p2pControl.DHTstore(sTopic + DHT_ALIVE_POSTFIX,
    9698                System.BitConverter.GetBytes(this.aliveMessageInterval));
    9799
    98100            if (!bolTopicStored || !bolSettingsStored)
    99101            {
    100                 GuiLogging("Storing Publishers ID or Publishers Settings wasn't possible.", NotificationLevel.Error);
     102                GuiLogging("Storing Publishers ID and/or Publishers Settings wasn't possible.", NotificationLevel.Error);
    101103                return false;
    102104            }
     
    133135        public virtual void Stop(PubSubMessageType msgType)
    134136        {
    135             // send unregister message to all subscribers
    136             int i = SendInternalMsg(msgType);
    137             GuiLogging("Unregister messages were sent to " + i.ToString() + " subscribers!", NotificationLevel.Info);
    138 
    139             //Still an error in dhtRemove... so at present ignored... - partially freezing the workspace forever...
    140             /*
    141              * if someone wants to call the Stop-method, but the peer is already down,
    142              * this will run into a problem (CrypWin.exe lives on), because of the
    143              * necessary workaround in P2PPeerMaster (Initializes Peer, if it isn't
    144              * initialized yet). This workaround was necessary, because of the gradual
    145              * execution of the PlugIns, so that the case could occur, that the Peer isn't
    146              * initialized by the PlugIn-method, but its Master-PlugIns want to use its
    147              * functions right now
    148              */
    149137            if (this.p2pControl != null && this.p2pControl.PeerStarted())
    150138            {
     
    153141
    154142                bool removeTopic = this.p2pControl.DHTremove(this.topic);
    155                 bool removeSettings = this.p2pControl.DHTremove(this.topic + this.sDHTSettingsPostfix);
     143                bool removeSettings = this.p2pControl.DHTremove(this.topic + DHT_ALIVE_POSTFIX);
    156144                string removeInfo = String.Empty;
    157145                if (removeTopic && removeSettings)
     
    165153                else
    166154                    GuiLogging("Neither Topic nor settings were removed from DHT.", NotificationLevel.Debug);
     155
     156                // send unregister message to all subscribers
     157                int i = SendInternalMsg(msgType);
     158                GuiLogging("Unregister messages were sent to " + i.ToString() + " subscribers!", NotificationLevel.Info);
    167159            }
    168160
     
    175167            }
    176168
     169            GuiLogging("Deregister message-received-events", NotificationLevel.Debug);
     170            this.p2pControl.OnPayloadMessageReceived -= p2pControl_OnPayloadMessageReceived;
     171            this.p2pControl.OnSystemMessageReceived -= p2pControl_OnSystemMessageReceived;
     172
    177173            GuiLogging("Publisher completely stopped!", NotificationLevel.Info);
    178174
     
    184180        #region private Methods (MessageReceived, SendInternalMsg, OnWaitingForAliveMsg, peerManagement_OnSubscriberRemoved)
    185181
    186         protected virtual void MessageReceived(PeerId sourceAddr, string sData)
    187         {
    188             PubSubMessageType msgType = this.p2pControl.GetMsgType(sData);
    189 
    190             if (msgType != PubSubMessageType.NULL)
    191             {
    192                 switch (msgType)
    193                 {
    194                     case PubSubMessageType.Register:
    195                         if (this.peerManagement.Add(sourceAddr))
    196                         {
    197                             GuiLogging("REGISTERED: Peer with ID " + sourceAddr, NotificationLevel.Info);
    198                             this.p2pControl.SendToPeer(PubSubMessageType.RegisteringAccepted, sourceAddr);
    199                         }
    200                         else
    201                         {
    202                             GuiLogging("ALREADY REGISTERED peer with ID " + sourceAddr, NotificationLevel.Info);
    203                         }
    204                         break;
    205                     case PubSubMessageType.Unregister:
    206                         if (this.peerManagement.Remove(sourceAddr))
    207                             GuiLogging("REMOVED peer " + sourceAddr + " because it had sent an unregister message", NotificationLevel.Info);
    208                         else
    209                             GuiLogging("ALREADY REMOVED or had not registered anytime. ID " + sourceAddr, NotificationLevel.Info);
    210                         break;
    211                     case PubSubMessageType.Alive:
    212                     case PubSubMessageType.Pong:
    213                         if (this.peerManagement.Update(sourceAddr))
    214                         {
    215                             GuiLogging("RECEIVED: " + msgType.ToString() + " Message from " + sourceAddr, NotificationLevel.Debug);
    216                         }
    217                         else
    218                         {
    219                             GuiLogging("UPDATE FAILED for " + sourceAddr + " because it hasn't registered first. " + msgType.ToString(), NotificationLevel.Info);
    220                         }
    221                         break;
    222                     case PubSubMessageType.Ping:
    223                         this.p2pControl.SendToPeer(PubSubMessageType.Pong, sourceAddr);
    224                         GuiLogging("REPLIED to a ping message from peer " + sourceAddr, NotificationLevel.Debug);
    225                         break;
    226                     case PubSubMessageType.Solution:
    227                         // Send solution msg to all subscriber peers and delete subList
    228                         Stop(msgType);
    229                         break;
    230                     case PubSubMessageType.Stop: //ignore this case. No subscriber can't command the Publisher to stop!
    231                         break;
    232                     default:
    233                         throw (new NotImplementedException());
    234                 } // end switch
    235                 if (timerWaitingForAliveMsg == null)
    236                     timerWaitingForAliveMsg = new Timer(OnWaitingForAliveMsg, null, this.aliveMessageInterval * 1000,
    237                         this.aliveMessageInterval * 1000);
    238             }
    239             // Received Data aren't PubSubMessageTypes or rather no action-relevant messages
    240             else
    241             {
    242                 GuiLogging("RECEIVED message from non subscribed peer: " + sData.Trim() + ", ID: " + sourceAddr, NotificationLevel.Debug);
     182        protected virtual void p2pControl_OnSystemMessageReceived(PeerId sender, PubSubMessageType msgType)
     183        {
     184            switch (msgType)
     185            {
     186                case PubSubMessageType.Register:
     187                    if (this.peerManagement.Add(sender))
     188                    {
     189                        GuiLogging("REGISTERED: Peer with ID " + sender, NotificationLevel.Info);
     190                        this.p2pControl.SendToPeer(PubSubMessageType.RegisteringAccepted, sender);
     191                    }
     192                    else
     193                    {
     194                        GuiLogging("ALREADY REGISTERED peer with ID " + sender, NotificationLevel.Info);
     195                    }
     196                    break;
     197                case PubSubMessageType.Unregister:
     198                    if (!this.peerManagement.Remove(sender))
     199                        GuiLogging("ALREADY REMOVED or had not registered anytime. ID " + sender, NotificationLevel.Info);
     200                    break;
     201                case PubSubMessageType.Alive:
     202                case PubSubMessageType.Pong:
     203                    break;
     204                case PubSubMessageType.Ping:
     205                    this.p2pControl.SendToPeer(PubSubMessageType.Pong, sender);
     206                    GuiLogging("REPLIED to a ping message from peer " + sender, NotificationLevel.Debug);
     207                    break;
     208                case PubSubMessageType.Solution:
     209                    // Send solution msg to all subscriber peers and delete subList
     210                    Stop(msgType);
     211                    break;
     212                case PubSubMessageType.Stop: //ignore this case. No subscriber can't command the Publisher to stop!
     213                    break;
     214                default:
     215                    throw (new NotImplementedException());
     216            } // end switch
     217            if (timerWaitingForAliveMsg == null)
     218                timerWaitingForAliveMsg = new Timer(OnWaitingForAliveMsg, null, this.aliveMessageInterval * 1000,
     219                    this.aliveMessageInterval * 1000);
     220
     221            if (msgType != PubSubMessageType.Unregister)
     222            {
     223                if(this.peerManagement.Update(sender))
     224                    GuiLogging("UPDATED Peer " + sender + " successfully.", NotificationLevel.Debug);
     225                else
     226                    GuiLogging("UPDATING Peer " + sender + " failed.", NotificationLevel.Debug);
     227            }
     228        }
     229
     230        protected virtual void p2pControl_OnPayloadMessageReceived(PeerId sender, byte[] data)
     231        {
     232            GuiLogging("RECEIVED message from non subscribed peer: " + UTF8Encoding.UTF8.GetString(data) + ", ID: " + sender, NotificationLevel.Debug);
     233            // if sender is already registered, update its entry in either case
     234            if (this.peerManagement.Update(sender))
     235            {
     236                GuiLogging("UPDATED Peer " + sender + " successfully.", NotificationLevel.Debug);
    243237            }
    244238        }
  • trunk/CrypPlugins/PeerToPeerPublisher/P2PPublisherSettings.cs

    r862 r1068  
    8787        /* FOR TESTING ISSUES */
    8888
    89         private int sendAliveMessageInterval = 20;
     89        private int sendAliveMessageInterval = 60;
    9090        [TaskPane("Alive Message Interval (in seconds)","In which interval do you wish to receive Alive-Messages from your Subscribers?"
    9191            ,"Subscriber Properties",0,false,DisplayLevel.Beginner,ControlType.NumericUpDown, ValidationType.RangeInteger, 10, 3600)]
  • trunk/CrypPlugins/PeerToPeerPublisher/SubscribersManagement.cs

    r1022 r1068  
    55using System.Collections;
    66
    7 /*
    8  * Everything works fine.
    9  * @CheckVitality: Don't know what is better. Run through two loops and save copying dict or copying dict and save a second loop...
    10  */
    11 
    127namespace Cryptool.Plugins.PeerToPeer
    138{
    14     public class PeerValue
    15     {
    16         public PeerId peerId;
    17         public DateTime dateTime;
    18 
    19         public PeerValue(PeerId pid, DateTime dt)
    20         {
    21             this.peerId = pid;
    22             this.dateTime = dt;
    23         }
    24     }
    25 
    269    public class SubscriberManagement
    2710    {
     
    3619        /// contains all active subscribers
    3720        /// </summary>
    38         private Dictionary<PeerId, PeerValue> checkList;
    39 
    40 
    41         /*TESTING*/
    42         protected HashSet<PeerId> activeSubsList;
    43 
    44 
     21        private Dictionary<PeerId, DateTime> checkList;
    4522        /// <summary>
    4623        /// when a peer is in this list, it will be deleted on the next vitality check
     
    6542        public SubscriberManagement(long expirationTime)
    6643        {
    67             this.activeSubsList = new HashSet<PeerId>();
    68 
    6944            this.dateTimeNow = new DateTime();
    70             this.checkList = new Dictionary<PeerId, PeerValue>();
     45            this.checkList = new Dictionary<PeerId, DateTime>();
    7146            this.secondChanceList = new HashSet<PeerId>();
    7247            this.ExpirationTime = expirationTime;
     
    8661                lock (this.checkList)
    8762                {
    88                     this.checkList.Add(subscriberId, new PeerValue(subscriberId, this.dateTimeNow));
    89                     this.activeSubsList.Add(subscriberId);
     63                    this.checkList.Add(subscriberId, this.dateTimeNow);
    9064                }
    9165                return true;
     
    10680            if (this.checkList.ContainsKey(subscriberId))
    10781            {
    108                 this.checkList[subscriberId].dateTime = this.dateTimeNow;
     82                this.checkList[subscriberId] = this.dateTimeNow;
    10983                // remove subscriber from this list, because it's updated now and hence alive!
    11084                if (this.secondChanceList.Contains(subscriberId))
     
    137111                    result = true;
    138112                }
    139                 if (this.activeSubsList.Contains(subId))
    140                 {
    141                     this.activeSubsList.Remove(subId);
    142                     result = true;
    143                 }
    144113
    145114                if (result && OnSubscriberRemoved != null)
     
    148117            return result;
    149118        }
    150 
    151         /* see alternative method */
    152119
    153120        /// <summary>
     
    164131            lock (this.checkList)
    165132            {
    166                 foreach (KeyValuePair<PeerId, PeerValue> entry in this.checkList)
     133                foreach (KeyValuePair<PeerId, DateTime> entry in this.checkList)
    167134                {
    168                     DateTime valueWithExpirationTime = entry.Value.dateTime.AddMilliseconds(ExpirationTime);
     135                    DateTime valueWithExpirationTime = entry.Value.AddMilliseconds(ExpirationTime);
    169136
    170137                    // if time is expired AND the ID is already in the secondChanceList --> Add to remove list
    171138                    if (this.dateTimeNow > valueWithExpirationTime && secondChanceList.Contains(entry.Key))
    172139                    {
    173                         removeSubscribersFromDict.Add(entry.Value.peerId);
     140                        removeSubscribersFromDict.Add(entry.Key);
    174141                    }
    175142                    else if (this.dateTimeNow > valueWithExpirationTime) //otherwise give a second chance
     
    189156        }
    190157
    191         /* alternative method, works with a copy of checkList, saves a foreach-loop, but produces load for copying */
    192         /*
    193         /// <summary>
    194         /// Removes all Subscribers which are long-rated outdated (expiration time is considered).
    195         /// The recently outdated subscribers will be added to the returned second chance list.
    196         /// </summary>
    197         /// <returns>all recently outdated subscribers</returns>
    198         public List<PeerId> CheckVitality()
    199         {
    200             this.dateTimeNow = DateTime.Now;
    201 
    202             lock (this.checkList)
    203             {
    204                 //don't know what is better. Run through two loops and save copying dict or copying dict and save a second loop...
    205                 Dictionary<string, PeerValue> checkListCopy = this.checkList;
    206                 foreach (KeyValuePair<string, PeerValue> entry in this.checkListCopy)
    207                 {
    208                     DateTime valueWithExpirationTime = entry.Value.dateTime.AddMilliseconds(ExpirationTime);
    209 
    210                     // if time is expired AND the ID is already in the secondChanceList --> Add to remove list
    211                     if (this.dateTimeNow > valueWithExpirationTime && secondChanceList.ContainsKey(entry.Key))
    212                     {
    213                         this.secondChanceList.Remove(removeSub.stringId);
    214                         // remove entry from ORIGINAL dictionary!
    215                         this.checkList.Remove(removeSub.stringId);
    216                         this.activeSubsList.Remove(removeSub.stringId);
    217 
    218                         if (OnSubscriberRemoved != null)
    219                             OnSubscriberRemoved(removeSub);
    220                     }
    221                     else if (this.dateTimeNow > valueWithExpirationTime) //otherwise give a second chance
    222                     {
    223                         this.secondChanceList.Add(entry.Key, entry.Value.peerId);
    224                     }
    225                 }
    226             } //end lock(this.checkList)
    227 
    228             return this.secondChanceList.Values.ToList<PeerId>();
    229         }
    230         */
    231 
    232158        public List<PeerId> GetAllSubscribers()
    233159        {
    234             return this.activeSubsList.ToList<PeerId>();
     160            return this.checkList.Keys.ToList<PeerId>();
    235161        }
    236162
     
    241167            this.secondChanceList.Clear();
    242168            this.secondChanceList = null;
    243             this.activeSubsList.Clear();
    244             this.activeSubsList = null;
    245169        }
    246170    }
  • trunk/CrypPlugins/PeerToPeerSubscriber/P2PSubscriber.cs

    r971 r1068  
    134134            if (e.PropertyName == "BtnRegister")
    135135            {
    136                 RegisterSubscriber();
     136                StartSubscriber();
    137137                GuiLogMessage("Subscriber registers with Publisher!", NotificationLevel.Info);
    138138            }
     
    141141                if (this.p2pSubscriber != null)
    142142                {
    143                     this.p2pSubscriber.SolutionFound("");
     143                    this.p2pSubscriber.SolutionFound(new byte[]{0});
    144144                    GuiLogMessage("Solution found message sent to Publisher.", NotificationLevel.Info);
    145145                }
     
    185185        {
    186186            if(this.p2pSubscriber != null)
    187                 this.p2pSubscriber.Stop(PubSubMessageType.Stop);
     187                this.p2pSubscriber.Stop(PubSubMessageType.Unregister);
    188188        }
    189189
     
    207207            if (this.settings.TopicName != null)
    208208            {
    209                 RegisterSubscriber();
     209                StartSubscriber();
    210210            }
    211211            else
     
    215215        }
    216216
    217         private void RegisterSubscriber()
     217        private void StartSubscriber()
    218218        {
    219219            if (this.p2pSubscriber == null)
     
    222222                this.p2pSubscriber.OnGuiMessage += new P2PSubscriberBase.GuiMessage(p2pSubscriber_OnGuiMessage);
    223223                this.p2pSubscriber.OnTextArrivedFromPublisher += new P2PSubscriberBase.TextArrivedFromPublisher(p2pSubscriber_OnTextArrivedFromPublisher);
    224                 this.p2pSubscriber.Register(this.settings.TopicName, (long)(this.settings.CheckPublishersAvailability * 1000),
     224            }
     225            this.p2pSubscriber.Start(this.settings.TopicName, (long)(this.settings.CheckPublishersAvailability * 1000),
    225226                    (long)(this.settings.PublishersReplyTimespan * 1000));
    226             }
    227             else
    228             {
    229                 this.p2pSubscriber.Register(this.settings.TopicName, (long)(this.settings.CheckPublishersAvailability * 1000),
    230                     (long)(this.settings.PublishersReplyTimespan * 1000));
    231             }
    232         }
    233 
    234         void p2pSubscriber_OnTextArrivedFromPublisher(string sData, PeerId pid)
    235         {
    236             this.Outputvalue = sData;
     227        }
     228
     229        void p2pSubscriber_OnTextArrivedFromPublisher(byte[] data, PeerId pid)
     230        {
     231            this.Outputvalue = UTF8Encoding.UTF8.GetString(data);
    237232        }
    238233
  • trunk/CrypPlugins/PeerToPeerSubscriber/P2PSubscriberBase.cs

    r1022 r1068  
    2121        public delegate void GuiMessage(string sData, NotificationLevel notificationLevel);
    2222        public event GuiMessage OnGuiMessage;
    23         public delegate void TextArrivedFromPublisher(string sData, PeerId pid);
     23        public delegate void TextArrivedFromPublisher(byte[] data, PeerId pid);
    2424        public event TextArrivedFromPublisher OnTextArrivedFromPublisher;
    2525        public delegate void ReceivedStopFromPublisher(PubSubMessageType stopType, string sData);
     
    3131        #region Variables
    3232
     33        private const string DHT_ALIVE_POSTFIX = "AliveMsg";
     34
    3335        private IP2PControl p2pControl;
    34         private string sDHTSettingsPostfix = "Settings";
    3536        private long sendAliveMessageInterval;
    3637        private long checkPublishersAvailability;
     
    9091        /* BEGIN: Only for experimental cases */
    9192
    92         public void SolutionFound(string sSolutionData)
     93        public void SolutionFound(byte[] solutionData)
    9394        {
    9495            SendMessage(actualPublisher, PubSubMessageType.Solution);
    95             this.p2pControl.SendToPeer(sSolutionData, actualPublisher.ToByteArray());
    96         }
     96            this.p2pControl.SendToPeer(solutionData, actualPublisher);
     97        }
     98
    9799        /* END: Only for experimental cases */
    98100
     
    103105        }
    104106
    105         public void Register(string sTopic, long checkPublishersAvailability, long publishersReplyTimespan)
    106         {
    107             this.p2pControl.OnPeerReceivedMsg += new P2PBase.P2PMessageReceived(MessageReceived);
     107        public void Start(string sTopic, long checkPublishersAvailability, long publishersReplyTimespan)
     108        {
     109            this.p2pControl.OnPayloadMessageReceived += new P2PPayloadMessageReceived(p2pControl_OnPayloadMessageReceived);
     110            this.p2pControl.OnSystemMessageReceived += new P2PSystemMessageReceived(p2pControl_OnSystemMessageReceived);
    108111
    109112            this.sTopic = sTopic;
    110113            this.checkPublishersAvailability = checkPublishersAvailability;
    111114            this.publisherReplyTimespan = publishersReplyTimespan;
    112 
     115            Register();
     116        }
     117
     118        private void Register()
     119        {
    113120            // because CheckPublishersAvailability checks this value, set it for the first time here...
    114121            // if bolStopped = true, the Timer for Checking Publishers liveliness doesn't start
     
    132139        }
    133140
    134         private void MessageReceived(PeerId sourceAddr, string sData)
    135         {
    136             if (sourceAddr != actualPublisher)
    137             {
    138                 GuiLogging("RECEIVED message from third party peer (not the publisher!): " + sData.Trim() + ", ID: " + sourceAddr, NotificationLevel.Debug);
     141        private void p2pControl_OnSystemMessageReceived(PeerId sender, PubSubMessageType msgType)
     142        {
     143            if (sender != actualPublisher)
     144            {
     145                GuiLogging("RECEIVED message from third party peer (not the publisher!): " + msgType.ToString() + ", ID: " + sender, NotificationLevel.Debug);
    139146                return;
    140147            }
    141 
    142             PubSubMessageType msgType = this.p2pControl.GetMsgType(sData);
    143 
    144148            switch (msgType)
    145149            {
     
    153157                    break;
    154158                case PubSubMessageType.Ping:
    155                     SendMessage(sourceAddr, PubSubMessageType.Pong);
    156                     GuiLogging("REPLIED to a ping message from " + sourceAddr, NotificationLevel.Debug);
     159                    SendMessage(sender, PubSubMessageType.Pong);
     160                    GuiLogging("REPLIED to a ping message from " + sender, NotificationLevel.Debug);
    157161                    break;
    158162                case PubSubMessageType.Register:
    159163                case PubSubMessageType.Unregister:
    160                     GuiLogging(msgType.ToString().ToUpper() + " received from PUBLISHER.", NotificationLevel.Warning);
     164                    GuiLogging(msgType.ToString().ToUpper() + " received from PUBLISHER.", NotificationLevel.Debug);
    161165                    // continuously try to get a unregister and than re-register with publisher
    162166                    Stop(msgType);
    163                     Register(this.sTopic,this.checkPublishersAvailability, this.publisherReplyTimespan);
     167                    Register();
    164168                    break;
    165169                case PubSubMessageType.Solution:
     
    178182                    }
    179183                    break;
    180                 // if the received Data couldn't be casted to enum,
    181                 // it must be some data
    182                 case PubSubMessageType.NULL:
    183                     // functionality swapped for better inheritance
    184                     Thread handlingOtherIncomingData = new Thread(new ParameterizedThreadStart(HandleIncomingData));
    185                     handlingOtherIncomingData.Start(new IncomingData(sourceAddr, sData));
    186                     break;
    187184                case PubSubMessageType.Alive:
    188185                default:
     
    192189        }
    193190
    194         // helper class to realize the necessary two parameters for the threading method HandleIncomingMethod
    195         private class IncomingData
    196         {
    197             public PeerId sourceAddr = null;
    198             public string sData = null;
    199 
    200             public IncomingData(PeerId sourceAddr, string sData)
    201             {
    202                 this.sourceAddr = sourceAddr;
    203                 this.sData = sData;
    204             }
    205         }
    206 
    207         private void HandleIncomingData(object incomData)
    208         {
    209             if (incomData is IncomingData)
    210             {
    211                 IncomingData incomingData = incomData as IncomingData;
    212                 HandleIncomingData(incomingData.sourceAddr, incomingData.sData);
    213             }
    214             else
    215             {
    216                 throw (new Exception("Wrong object type in HandleIncomingData"));
    217             }
     191        private void p2pControl_OnPayloadMessageReceived(PeerId sender, byte[] data)
     192        {
     193            if (sender != actualPublisher)
     194            {
     195                GuiLogging("RECEIVED message from third party peer (not the publisher!): " + UTF8Encoding.UTF8.GetString(data) + ", ID: " + sender, NotificationLevel.Debug);
     196                return;
     197            }
     198            // functionality swapped for better inheritance
     199            HandleIncomingData(sender, data);
    218200        }
    219201
     
    223205        /// <param name="senderId"></param>
    224206        /// <param name="sData"></param>
    225         protected virtual void HandleIncomingData(PeerId senderId, string sData)
     207        protected virtual void HandleIncomingData(PeerId senderId, byte[] data)
    226208        {
    227209            GuiLogging("RECEIVED: Message from '" + senderId
    228                     + "' with data: '" + sData + "'", NotificationLevel.Debug);
     210                    + "' with data: '" + UTF8Encoding.UTF8.GetString(data) + "'", NotificationLevel.Debug);
    229211
    230212            if (OnTextArrivedFromPublisher != null)
    231                 OnTextArrivedFromPublisher(sData, senderId);
     213                OnTextArrivedFromPublisher(data, senderId);
    232214        }
    233215
     
    288270        }
    289271
     272        /// <summary>
     273        /// Returns the actual Publishers ID or null, when a publisher wasn't found in the DHT. In the second case,
     274        /// a Timer will be started, to check periodically the DHT entry.
     275        /// When the publishers entry changed the Publishers ID, a Register-message will be send to the new Publisher.
     276        /// The Timer for periodically checking the Publishers availability is also started here.
     277        /// </summary>
     278        /// <returns>the actual Publishers ID or null, when a publisher wasn't found in the DHT</returns>
    290279        private PeerId CheckPublisherAvailability()
    291280        {
     
    300289                    timerRegisteringNotPossible = new Timer(OnRegisteringNotPossible, null, 10000, 10000);
    301290                }
     291                GuiLogging("Publisher wasn't found in DHT or settings didn't stored on the right way.", NotificationLevel.Debug);
     292                //GuiLogging("Publisher wasn't found in DHT or settings didn't stored on the right way.", NotificationLevel.Warning);
    302293                return null;
    303294            }
    304295
    305             byte[] byteISettings = this.p2pControl.DHTload(this.sTopic + this.sDHTSettingsPostfix);
     296            byte[] byteISettings = this.p2pControl.DHTload(this.sTopic + DHT_ALIVE_POSTFIX);
    306297            if (byteISettings == null)
    307298            {
    308                 GuiLogging("Can't find settings from Publisher for the Subscriber.", NotificationLevel.Error);
     299                GuiLogging("Can't find AliveMsg-Settings from Publisher for the Subscriber.", NotificationLevel.Error);
    309300                return null;
    310301            }
     
    313304            pid = this.p2pControl.GetPeerID(bytePubId);
    314305            if (actualPublisher == null) //first time initialization
     306            {
    315307                actualPublisher = pid;
    316 
    317             GuiLogging("RECEIVED: Publishers' peer name '" + pid + "', Alive-Msg-Interval: " + sendAliveMessageInterval / 1000 + " sec!", NotificationLevel.Debug);
     308                GuiLogging("First time received publishers ID.", NotificationLevel.Debug);
     309            }
     310            else if (actualPublisher != pid)
     311            {
     312                GuiLogging("Publisher has been changed from ID '" +  actualPublisher + "' to '" + pid + "'", NotificationLevel.Debug);
     313                actualPublisher = pid;
     314                // because the publisher has changed, send a new register msg
     315                SendMessage(actualPublisher, PubSubMessageType.Register);
     316            }
     317
     318            GuiLogging("RECEIVED: Publishers' peer ID '" + pid + "', Alive-Msg-Interval: " + sendAliveMessageInterval / 1000 + " sec!", NotificationLevel.Debug);
    318319
    319320            // setting timer to check periodical the availability of the publishing peer
     
    334335            PeerId newPubId = CheckPublisherAvailability();
    335336
    336             if (newPubId == null)
    337             {
    338                 GuiLogging("Publisher wasn't found in DHT or settings didn't stored on the right way.", NotificationLevel.Warning);
    339                 return;
    340             }
    341             if (newPubId != actualPublisher)
    342             {
    343                 //Handle case, when publisher changed or isn't active at present (don't reply on response)
    344                 GuiLogging("CHANGED: Publisher from '" + actualPublisher
    345                     + "' to '" + newPubId + "'!", NotificationLevel.Info);
    346                 actualPublisher = newPubId;
    347                 // because the publisher has changed, send a new register msg
    348                 SendMessage(actualPublisher, PubSubMessageType.Register);
    349             }
    350             else
     337            if (newPubId == actualPublisher)
    351338            {
    352339                // Timer will be only stopped, when OnMessageReceived-Event received
     
    367354        {
    368355            GuiLogging("TIMEOUT: Waiting for registering accepted message from publisher!", NotificationLevel.Warning);
    369             // TODO: anything
     356            // try to register again
     357            Register();
    370358        }
    371359
     
    424412            }
    425413            #endregion
    426 
    427             this.p2pControl.OnPeerReceivedMsg -= MessageReceived;
     414            GuiLogging("All Timers were stopped successfully", NotificationLevel.Debug);
     415
     416            this.p2pControl.OnSystemMessageReceived -= p2pControl_OnSystemMessageReceived;
     417            this.p2pControl.OnPayloadMessageReceived -= p2pControl_OnPayloadMessageReceived;
    428418
    429419            this.Started = false;
     420            GuiLogging("Subscriber is completely stopped",NotificationLevel.Debug);
    430421        }
    431422
  • trunk/CrypPlugins/PeerToPeerSubscriber/P2PSubscriberSettings.cs

    r872 r1068  
    8888        /* FOR TESTING ISSUES */
    8989
    90         private int checkPublishersAvailability = 60;
     90        private int checkPublishersAvailability = 240;
    9191        [TaskPane("Check Publisher Interval (in sec)","To check liveness or possibly changed publishing peer in intervals","Intervals",0,false,DisplayLevel.Beginner,ControlType.NumericUpDown, ValidationType.RangeInteger,20,int.MaxValue)]
    9292        public int CheckPublishersAvailability
     
    107107        }
    108108
    109         private int publishersReplyTimespan = 5;
    110         [TaskPane("Publisher Reply Timespan (in sec)", "When checking publishers availability, ping message is sent. The publisher must answer with a pong message in the timespan!", "Intervals", 0, false, DisplayLevel.Beginner, ControlType.NumericUpDown, ValidationType.RangeInteger, 2, 60)]
     109        private int publishersReplyTimespan = 10;
     110        [TaskPane("Publisher Reply Timespan (in sec)", "When checking publishers availability, ping message is sent. The publisher must answer with a pong message in the timespan!", "Intervals", 0, false, DisplayLevel.Beginner, ControlType.NumericUpDown, ValidationType.RangeInteger, 2, 120)]
    111111        public int PublishersReplyTimespan
    112112        {
  • trunk/CrypPlugins/PeerToPeerWorker/P2PWorker.cs

    r971 r1068  
    8484                if (this.p2pWorker != null)
    8585                {
    86                     this.p2pWorker.SolutionFound("");
     86                    this.p2pWorker.SolutionFound(new byte[]{0});
    8787                    GuiLogMessage("Solution found message sent to Manager.", NotificationLevel.Info);
    8888                }
     
    127127            if (readyForExecution)
    128128                GuiLogMessage("KeySearcherControl_OnStatusChanged thrown, readyForExecution = true",NotificationLevel.Info);
    129                 //this.KeySearcherControl.bruteforcePattern();
    130129        }
    131130
     
    230229        {
    231230            if(this.p2pWorker != null)
    232                 this.p2pWorker.Stop(PubSubMessageType.Stop);
     231                this.p2pWorker.Stop(PubSubMessageType.Unregister);
    233232        }
    234233
     
    271270                this.p2pWorker.OnReceivedStopMessageFromPublisher += new P2PSubscriberBase.ReceivedStopFromPublisher(p2pWorker_OnReceivedStopMessageFromPublisher);
    272271
    273                 this.p2pWorker.Register(this.settings.TopicName, (long)(this.settings.CheckPublishersAvailability * 1000),
     272                this.p2pWorker.Start(this.settings.TopicName, (long)(this.settings.CheckPublishersAvailability * 1000),
    274273                    (long)(this.settings.PublishersReplyTimespan * 1000));
    275274            }
    276275            else
    277276            {
    278                 this.p2pWorker.Register(this.settings.TopicName, (long)(this.settings.CheckPublishersAvailability * 1000),
     277                this.p2pWorker.Start(this.settings.TopicName, (long)(this.settings.CheckPublishersAvailability * 1000),
    279278                    (long)(this.settings.PublishersReplyTimespan * 1000));
    280279            }
     
    310309        }
    311310
    312         void p2pWorker_OnTextArrivedFromPublisher(string sData, PeerId pid)
    313         {
    314             this.Outputvalue = sData;
     311        void p2pWorker_OnTextArrivedFromPublisher(byte[] data, PeerId pid)
     312        {
     313            this.Outputvalue = UTF8Encoding.UTF8.GetString(data);
    315314        }
    316315
  • trunk/CrypPlugins/PeerToPeerWorker/P2PWorkerBase.cs

    r980 r1068  
    88using KeySearcher;
    99
    10 /*
    11  * TODO:
    12  * - Serializing ResultList is buggy when converting decryption byte[]
    13  *   to String and following deserializing in P2PManager
    14  * - Error gets thrown after ending bruteforcing once. "set-Property not found" (oder so)
    15  *   I think it's an error in KeySearcher_IControl --> method keySearcher_OnAllMasterControlsInitialized
    16  *   where I set the KeyPattern and additional the WildcardKey manual...
    17  */
    18 
    1910namespace Cryptool.Plugins.PeerToPeer
    2011{
     
    5546        /// </summary>
    5647        private KeyPattern patternForValidateIncomingPatterns;
     48        /// <summary>
     49        /// this value is always the actual pattern, which is in progress
     50        /// </summary>
     51        private KeyPattern actualProcessingPattern;
    5752        private IControlKeySearcher keySearcherControl;
    5853        private IControlCost costControl;
     
    135130        /// <param name="senderId"></param>
    136131        /// <param name="sData"></param>
    137         protected override void HandleIncomingData(PeerId senderId, string sData)
     132        protected override void HandleIncomingData(PeerId senderId, byte[] data)
    138133        {
    139134            // returns null if the data aren't a valid KeyPattern.
    140             KeyPattern receivedKeyPattern = patternForValidateIncomingPatterns.DeserializeFromString(sData);
     135            KeyPattern receivedKeyPattern = patternForValidateIncomingPatterns.Deserialize(data);
    141136            if (receivedKeyPattern != null)
    142137            {
     
    158153            else
    159154            {
    160                 base.HandleIncomingData(senderId, sData);
     155                base.HandleIncomingData(senderId, data);
    161156            }
    162157        }
     
    175170        private void StartProcessing(KeyPattern receivedKeyPattern)
    176171        {
    177             GuiLogging("Starting Bruteforcing the incoming pattern: '" + receivedKeyPattern.ToString() + "'", NotificationLevel.Info);
     172            GuiLogging("Starting Bruteforcing the incoming WildCardKey: '" + receivedKeyPattern.WildcardKey + "'", NotificationLevel.Info);
    178173
    179174            if (OnKeyPatternReceived != null)
    180175                OnKeyPatternReceived(receivedKeyPattern);
    181176            this.currentlyWorking = true;
     177            // to access this pattern in every method, where it's meaningful for information or processing reasons
     178            this.actualProcessingPattern = receivedKeyPattern;
    182179            // Commit pattern to the KeySearcherControl and wait for result(s)
    183180            this.keySearcherControl.StartBruteforcing(receivedKeyPattern);
     
    192189                    + bestResult.value.ToString() + ". Decrypted result: '" + UTF8Encoding.UTF8.GetString(bestResult.decryption)
    193190                    + "'", NotificationLevel.Info);
    194                 SolutionFound(SerializeKeySearcherResult(top10List));
     191
     192                KeySearcherResult keySearcherResult = new KeySearcherResult();
     193                SolutionFound(keySearcherResult.SerializeResult(top10List));
     194
     195                if (OnFinishedBruteforcingThePattern != null)
     196                    OnFinishedBruteforcingThePattern(this.actualProcessingPattern);
     197
     198                // because bruteforcing the actual pattern was successful, delete information
     199                this.actualProcessingPattern = null;
    195200                GuiLogging("Serialized result list sended to Managing-Peer.", NotificationLevel.Debug);
    196201            }
     
    204209                this.currentlyWorking = false;
    205210        }
    206 
    207         // only the first byte of the decryption byte[] are serialized - maybe avoiding the splitting error in P2PManager.Deserialize...
    208         /*
    209          * serialization information: 3 fields per data set in the following order:
    210          * 1) value (double)
    211          * 2) key (string)
    212          * 3) decryption (byte[])
    213          */
    214         private string seperator = "#;#";
    215         private string dataSetSeperator = "|**|";
    216         private string SerializeKeySearcherResult(LinkedList<KeySearcher.KeySearcher.ValueKey> top10List)
    217         {
    218             StringBuilder sbRet = new StringBuilder();
    219             foreach (KeySearcher.KeySearcher.ValueKey valKey in top10List)
    220             {
    221                 //sbRet.Append(valKey.value.ToString() + seperator + valKey.key + seperator + UTF8Encoding.UTF8.GetString(valKey.decryption) + dataSetSeperator);
    222                 sbRet.Append(valKey.value.ToString() + seperator + valKey.key + seperator + "replaced" + dataSetSeperator);
    223             }
    224             string sRet = sbRet.ToString();
    225             // cut off last dataSetSeperator
    226             sRet = sRet.Substring(0, sRet.Length - dataSetSeperator.Length);
    227             return sRet;
    228         }
    229211    }
    230212}
  • trunk/CrypPlugins/PeerToPeerWorker/P2PWorkerSettings.cs

    r971 r1068  
    8888        /* FOR TESTING ISSUES */
    8989
    90         private int checkPublishersAvailability = 60;
     90        private int checkPublishersAvailability = 240;
    9191        [TaskPane("Check Publisher Interval (in sec)","To check liveness or possibly changed publishing peer in intervals","Intervals",0,false,DisplayLevel.Beginner,ControlType.NumericUpDown, ValidationType.RangeInteger,20,int.MaxValue)]
    9292        public int CheckPublishersAvailability
     
    107107        }
    108108
    109         private int publishersReplyTimespan = 5;
     109        private int publishersReplyTimespan = 10;
    110110        [TaskPane("Publisher Reply Timespan (in sec)", "When checking publishers availability, ping message is sent. The publisher must answer with a pong message in the timespan!", "Intervals", 0, false, DisplayLevel.Beginner, ControlType.NumericUpDown, ValidationType.RangeInteger, 2, 60)]
    111111        public int PublishersReplyTimespan
Note: See TracChangeset for help on using the changeset viewer.