Ignore:
Timestamp:
Nov 17, 2009, 1:05:15 PM (12 years ago)
Author:
arnold
Message:

Buggy P2P version

Location:
trunk/CrypPlugins/PeerToPeerSubscriber
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/CrypPlugins/PeerToPeerSubscriber/P2PSubscriber.cs

    r836 r862  
    2626
    2727/*
     28 * IDEAS:
     29 * - Publisher takes subscriber list out of the DHT and registered
     30 *   itself with all subscribers pro-active (handle Register-Msg in Subscriber!)
     31 *
    2832 * TODO:
    29  * - Receive "add"-Message from Publisher (2-way-handshake),
    30  *   so you can be sure that the Publisher exists at present
    3133 * - Handle "publisher-changed" case (reconfirm registration, etc.)
    32  * - Check availability of Publisher periodically (make GuiLogMsg)
    33  * - Unregister subscriber on Stop-Action
    3434 */
    3535
     
    4848        private long sendAliveMessageInterval;
    4949        private long checkPublishersAvailability;
    50         /// <summary>
    51         /// if true, check whether a new Publisher is the actual one
    52         /// and renew Settings
    53         /// </summary>
    54         private bool bolStopped = true;
    5550
    5651        private P2PSubscriberSettings settings;
     
    7065        /// </summary>
    7166        private Timer timerCheckPubAvailability;
    72         private byte[] actualPublisher;
     67        /// <summary>
     68        /// this timer gets started when the availability of the publisher,
     69        /// at which the subscriber had registered, is checked. If the timer
     70        /// callback is called and no Pong-message was received, the probability
     71        /// that the Publisher is down is high!
     72        /// </summary>
     73        private Timer timeoutForPublishersPong;
     74        /// <summary>
     75        /// After register message is sent to publisher, this timer gets started.
     76        /// If the publisher doesn't response with a RegisteringAccepted-Message,
     77        /// the probability that the publisher is down is high!
     78        /// </summary>
     79        private Timer timeoutForPublishersRegAccept;
     80        /// <summary>
     81        /// PeerID of the actual publisher. This ID is will be checked continious
     82        /// on liveliness and/or updated if Publisher had changed.
     83        /// </summary>
     84        private string actualPublisher;
    7385
    7486        #endregion
     
    127139        #endregion
    128140
     141        private void P2PMaster_OnPeerReceivedMsg(string sSourceAddr, string sData)
     142        {
     143            MessageReceived(sSourceAddr, sData);
     144        }
     145
    129146        private void P2PMaster_OnStatusChanged(IControl sender, bool readyForExecution)
    130147        {
     
    146163        {
    147164            this.settings = new P2PSubscriberSettings(this);
     165            this.settings.PropertyChanged += new PropertyChangedEventHandler(settings_PropertyChanged);
     166            this.settings.TaskPaneAttributeChanged += new TaskPaneAttributeChangedHandler(settings_TaskPaneAttributeChanged);
     167        }
     168
     169        void settings_TaskPaneAttributeChanged(ISettings settings, TaskPaneAttributeChangedEventArgs args)
     170        {
     171            // throw new NotImplementedException();
     172        }
     173
     174        private void settings_PropertyChanged(object sender, PropertyChangedEventArgs e)
     175        {
     176            if (e.PropertyName == "BtnUnregister")
     177            {
     178                StopActiveWork();
     179                GuiLogMessage("Subscriber unregistered from Publisher!", NotificationLevel.Info);
     180            }
     181            if (e.PropertyName == "BtnRegister")
     182            {
     183                Register();
     184                GuiLogMessage("Subscriber registers with Publisher!", NotificationLevel.Info);
     185            }
     186            if (e.PropertyName == "BtnSolutionFound")
     187            {
     188                SendMessage(actualPublisher, PubSubMessageType.Solution);
     189                GuiLogMessage("Solution found message sent to Publisher.", NotificationLevel.Info);
     190            }
    148191        }
    149192
     
    168211        public void PreExecution()
    169212        {
    170             bolStopped = false;
    171213        }
    172214
     
    178220        public void Pause()
    179221        {
    180             //throw new NotImplementedException();
     222            StopActiveWork();
    181223        }
    182224
    183225        public void Stop()
    184226        {
    185             bolStopped = true;
    186             try
    187             {
    188                 if (this.timerSendingAliveMsg != null)
    189                 {
    190                     this.timerSendingAliveMsg.Dispose();
    191                     this.timerSendingAliveMsg = null;
    192                 }
    193                 if (this.timerRegisteringNotPossible != null)
    194                 {
    195                     this.timerRegisteringNotPossible.Dispose();
    196                     this.timerRegisteringNotPossible = null;
    197                 }
    198             }
    199             catch (Exception ex)
    200             {
    201                 GuiLogMessage(ex.ToString(), NotificationLevel.Error);
    202             }
     227            StopActiveWork();
    203228        }
    204229
     
    211236        }
    212237        #endregion
    213 
    214         #region Methods, EventHandler, etc. for Subscriber
    215238
    216239        public void Execute()
     
    222245                return;
    223246            }
    224             if (this.settings.TaskName != null)
    225             {
    226                 byte[] bytePubId = CheckPublisherAvailability();
    227                 // if DHT Entry for Task is empty, there exist no Publisher at present.
    228                 // The method PublisherIsAlive starts a Timer for this case to continous proof Publisher-DHT-Entry
    229                 if (bytePubId != null)
    230                     SendMsgToPublisher(bytePubId, PubSubMessageType.Register);
     247            if (this.settings.TopicName != null)
     248            {
     249                Register();
    231250            }
    232251            else
     
    236255        }
    237256
    238         private void SendMsgToPublisher(byte[] pubPeerId, PubSubMessageType msgType)
    239         {
    240             if (timerSendingAliveMsg == null && !bolStopped)
     257        #region INotifyPropertyChanged Members
     258
     259        public event System.ComponentModel.PropertyChangedEventHandler PropertyChanged;
     260
     261        public void OnPropertyChanged(string name)
     262        {
     263            EventsHelper.PropertyChanged(PropertyChanged, this, new PropertyChangedEventArgs(name));
     264        }
     265
     266        public event PluginProgressChangedEventHandler OnPluginProcessChanged;
     267
     268        private void ProgressChanged(double value, double max)
     269        {
     270            EventsHelper.ProgressChanged(OnPluginProgressChanged, this, new PluginProgressEventArgs(value, max));
     271        }
     272
     273        private void GuiLogMessage(string p, NotificationLevel notificationLevel)
     274        {
     275            EventsHelper.GuiLogMessage(OnGuiLogNotificationOccured, this, new GuiLogEventArgs(p, this, notificationLevel));
     276        }
     277
     278        #endregion
     279
     280        #region Subscriber methods
     281
     282        /// <summary>
     283        /// if true, check whether a new Publisher is the actual one
     284        /// and renew Settings
     285        /// </summary>
     286        private bool bolStopped = true;
     287
     288        private void Register()
     289        {
     290            string sPubId = CheckPublisherAvailability();
     291            // if DHT Entry for Task is empty, there exist no Publisher at present.
     292            // The method PublisherIsAlive starts a Timer for this case to continous proof Publisher-DHT-Entry
     293            if (sPubId != null)
     294            {
     295                SendMessage(sPubId, PubSubMessageType.Register);
     296                long interval = this.settings.PublishersReplyTimespan * 1000;
     297                if (this.timeoutForPublishersRegAccept == null)
     298                    this.timeoutForPublishersRegAccept = new Timer(OnTimeoutRegisteringAccepted, null, interval, interval);
     299                this.bolStopped = false;
     300            }
     301        }
     302
     303        private void MessageReceived(string sSourceAddr, string sData)
     304        {
     305            if (sSourceAddr != actualPublisher)
     306            {
     307                GuiLogMessage("RECEIVED message from third party peer (not the publisher!): " + sData.Trim() + ", ID: " + sSourceAddr, NotificationLevel.Info);
     308                return;
     309            }
     310
     311            PubSubMessageType msgType = this.P2PMaster.GetMsgType(sData);
     312
     313            switch (msgType)
     314            {
     315                case PubSubMessageType.RegisteringAccepted:
     316                    GuiLogMessage("REGISTERING ACCEPTED received from publisher!", NotificationLevel.Info);
     317                    if (this.timeoutForPublishersRegAccept != null)
     318                    {
     319                        this.timeoutForPublishersRegAccept.Dispose();
     320                        this.timeoutForPublishersRegAccept = null;
     321                    }
     322                    break;
     323                case PubSubMessageType.Ping:
     324                    SendMessage(sSourceAddr, PubSubMessageType.Pong);
     325                    GuiLogMessage("REPLIED to a ping message from " + sSourceAddr, NotificationLevel.Info);
     326                    break;
     327                case PubSubMessageType.Register:
     328                case PubSubMessageType.Unregister:
     329                    /* can't work the right way, because at present the
     330                     * publisher can't remove information of the DHT
     331                     * (point of entry for subscribers) */
     332                    GuiLogMessage(msgType.ToString().ToUpper() + " received from PUBLISHER.", NotificationLevel.Warning);
     333                    // continuously try to get a unregister and than re-register with publisher
     334                    StopActiveWork();
     335                    Register();
     336                    break;
     337                case PubSubMessageType.Solution:
     338                    StopActiveWork();
     339                    GuiLogMessage("Another Subscriber had found the solution!",NotificationLevel.Info);
     340                    break;
     341                case PubSubMessageType.Stop:
     342                    StopActiveWork();
     343                    GuiLogMessage("STOP received from publisher. Subscriber is stopped!", NotificationLevel.Warning);
     344                    break;
     345                case PubSubMessageType.Pong:
     346                    if (this.timeoutForPublishersPong != null)
     347                    {
     348                        this.timeoutForPublishersPong.Dispose();
     349                        this.timeoutForPublishersPong = null;
     350                    }
     351                    break;
     352                // if the received Data couldn't be casted to enum,
     353                // it must be text-data
     354                case PubSubMessageType.NULL:
     355                    GuiLogMessage("RECEIVED: Message from '" + sSourceAddr
     356                    + "' with data: '" + sData + "'", NotificationLevel.Info);
     357                    Outputvalue = sData;
     358                    break;
     359                case PubSubMessageType.Alive:
     360                default:
     361                    // not possible at the moment
     362                    break;
     363            }
     364        }
     365
     366        private void SendMessage(string pubPeerId, PubSubMessageType msgType)
     367        {
     368            if (timerSendingAliveMsg == null && !this.bolStopped)
    241369                timerSendingAliveMsg = new Timer(OnSendAliveMessage, null, sendAliveMessageInterval, sendAliveMessageInterval);
    242370
     
    245373                case PubSubMessageType.Register:
    246374                    // stop "RegisteringNotPossibleTimer
    247                     if(timerRegisteringNotPossible != null)
     375                    if (timerRegisteringNotPossible != null)
     376                    {
    248377                        timerRegisteringNotPossible.Dispose();
    249 
    250                     // send register message to the publisher peer
    251                     this.P2PMaster.SendToPeer("regi", pubPeerId);
    252                     GuiLogMessage("Register message sent to Publishing", NotificationLevel.Info);
     378                        timerRegisteringNotPossible = null;
     379                    }
    253380                    break;
    254381                case PubSubMessageType.Alive:
    255                     this.P2PMaster.SendToPeer("aliv", pubPeerId);
    256                     GuiLogMessage("Alive message sent to Publisher",NotificationLevel.Info);
    257                     break;
     382                case PubSubMessageType.Ping:
    258383                case PubSubMessageType.Pong:
    259                     this.P2PMaster.SendToPeer("pong", pubPeerId);
    260                     GuiLogMessage("Pong message sent to Publisher", NotificationLevel.Info);
     384                case PubSubMessageType.Unregister:
     385                    break;
     386                case PubSubMessageType.Solution:
     387                    StopActiveWork();
    261388                    break;
    262389                default:
    263                     break;
    264             }
     390                    GuiLogMessage("No Message sent, because MessageType wasn't supported: " + msgType.ToString(),NotificationLevel.Warning);
     391                    return;
     392            }
     393            this.P2PMaster.SendToPeer(msgType, pubPeerId);
     394
     395            // don't show every single alive message
     396            if(msgType != PubSubMessageType.Alive)
     397                GuiLogMessage(msgType.ToString() + " message sent to Publisher", NotificationLevel.Info);
    265398        }
    266399
     
    269402        private void OnRegisteringNotPossible(object state)
    270403        {
    271             byte[] bytePubId = CheckPublisherAvailability();
     404            string sPubId = CheckPublisherAvailability();
    272405            // if DHT Entry for Task is empty, there exist no Publisher at present.
    273406            // The method PublisherIsAlive starts a Timer for this case to continous proof Publisher-DHT-Entry
    274             if (bytePubId != null)
    275                 SendMsgToPublisher(bytePubId, PubSubMessageType.Register);
     407            if (sPubId != null)
     408                SendMessage(sPubId, PubSubMessageType.Register);
    276409        }
    277410
    278411        private void OnSendAliveMessage(object state)
    279412        {
    280             SendMsgToPublisher(actualPublisher, PubSubMessageType.Alive);
    281         }
    282 
    283         private void P2PMaster_OnPeerReceivedMsg(byte[] byteSourceAddr, string sData)
    284         {
    285             if (sData.Trim() == "ping")
    286             {
    287                 SendMsgToPublisher(byteSourceAddr, PubSubMessageType.Pong);
    288                 GuiLogMessage("REPLIED to a ping message from the publisher", NotificationLevel.Info);
    289             }
    290             else
    291             {
    292                 GuiLogMessage("RECEIVED: Message from '" + P2PMaster.ConvertPeerId(byteSourceAddr)
    293                     + "' with data: '" + sData + "'", NotificationLevel.Info);
    294                 Outputvalue = sData;
    295             }
    296         }
    297 
    298         private byte[] CheckPublisherAvailability()
    299         {
    300             byte[] bytePubId = P2PMaster.DHTload(this.settings.TaskName);
     413            SendMessage(actualPublisher, PubSubMessageType.Alive);
     414        }
     415
     416        private string CheckPublisherAvailability()
     417        {
     418            byte[] bytePubId = P2PMaster.DHTload(this.settings.TopicName);
    301419            if (bytePubId == null)
    302420            {
    303                 if (timerRegisteringNotPossible == null && !bolStopped)
     421                if (timerRegisteringNotPossible == null && !this.bolStopped)
    304422                {
    305423                    // if DHT value doesn't exist at this moment, wait for 10 seconds and try again
     
    308426                return null;
    309427            }
    310             byte[] byteISettings = P2PMaster.DHTload(this.settings.TaskName + this.sDHTSettingsPostfix);
     428
     429            byte[] byteISettings = P2PMaster.DHTload(this.settings.TopicName + this.sDHTSettingsPostfix);
    311430            if (byteISettings == null)
    312431            {
     
    316435            sendAliveMessageInterval = System.BitConverter.ToInt32(byteISettings, 0);
    317436
    318             string sPublisherName = P2PMaster.ConvertPeerId(bytePubId);
    319             GuiLogMessage("RECEIVED: Publishers' peer name '" + sPublisherName + "', Alive-Msg-Interval: " + sendAliveMessageInterval / 1000 + " sec!", NotificationLevel.Info);
     437            string sPubId = UTF8Encoding.UTF8.GetString(bytePubId);
     438            GuiLogMessage("RECEIVED: Publishers' peer name '" + sPubId + "', Alive-Msg-Interval: " + sendAliveMessageInterval / 1000 + " sec!", NotificationLevel.Info);
    320439
    321440            if (actualPublisher == null) //first time initialization
    322                 actualPublisher = bytePubId;
     441                actualPublisher = sPubId;
    323442
    324443            checkPublishersAvailability = this.settings.CheckPublishersAvailability * 1000;
    325444
    326445            // setting timer to check periodical the availability of the publishing peer
    327             if (timerCheckPubAvailability == null && !bolStopped)
     446            if (timerCheckPubAvailability == null && !this.bolStopped)
    328447                timerCheckPubAvailability = new Timer(OnCheckPubAvailability, null, checkPublishersAvailability, checkPublishersAvailability);
    329448
    330             return bytePubId;
     449            return sPubId;
    331450        }
    332451
    333452        private void OnCheckPubAvailability(object state)
    334453        {
    335             byte[] newPubId = CheckPublisherAvailability();
    336 
    337             string sNewPubId = P2PMaster.ConvertPeerId(newPubId);
    338             string sActualPeerId = P2PMaster.ConvertPeerId(actualPublisher);
    339             if (sNewPubId != sActualPeerId)
     454            string sNewPubId = CheckPublisherAvailability();
     455
     456            if (sNewPubId == null)
     457            {
     458                GuiLogMessage("Publisher wasn't found in DHT or settings didn't stored on the right way.", NotificationLevel.Warning);
     459                return;
     460            }
     461            if (sNewPubId != actualPublisher)
    340462            {
    341463                //Handle case, when publisher changed or isn't active at present (don't reply on response)
    342                 GuiLogMessage("CHANGED: Publisher from '" + sActualPeerId
     464                GuiLogMessage("CHANGED: Publisher from '" + actualPublisher
    343465                    + "' to '" + sNewPubId + "'!", NotificationLevel.Info);
    344             }
    345             SendMsgToPublisher(newPubId, PubSubMessageType.Ping);
    346             // TODO: handle asynchronous reply or timeout ...
    347             // bool unansweredPingToPub = true;
    348             // //Start Timer with settings-interval to check whether a pong arrived
    349             // this.settings.PublishersReplyTimespan
    350         }
    351 
    352         #endregion
    353 
    354         #region INotifyPropertyChanged Members
    355 
    356         public event System.ComponentModel.PropertyChangedEventHandler PropertyChanged;
    357 
    358         public void OnPropertyChanged(string name)
    359         {
    360             EventsHelper.PropertyChanged(PropertyChanged, this, new PropertyChangedEventArgs(name));
    361         }
    362 
    363         public event PluginProgressChangedEventHandler OnPluginProcessChanged;
    364 
    365         private void ProgressChanged(double value, double max)
    366         {
    367             EventsHelper.ProgressChanged(OnPluginProgressChanged, this, new PluginProgressEventArgs(value, max));
    368         }
    369 
    370         private void GuiLogMessage(string p, NotificationLevel notificationLevel)
    371         {
    372             EventsHelper.GuiLogMessage(OnGuiLogNotificationOccured, this, new GuiLogEventArgs(p, this, notificationLevel));
    373         }
    374 
     466                actualPublisher = sNewPubId;
     467                // because the publisher has changed, send a new register msg
     468                SendMessage(actualPublisher, PubSubMessageType.Register);
     469            }
     470            else
     471            {
     472                // Timer will be only stopped, when OnMessageReceived-Event received
     473                // a Pong-Response from the publisher!
     474                SendMessage(actualPublisher, PubSubMessageType.Ping);
     475                if (timeoutForPublishersPong == null)
     476                {
     477                    long interval = this.settings.PublishersReplyTimespan * 1000;
     478                    timeoutForPublishersPong = new Timer(OnTimeoutPublishersPong, null, interval, interval);
     479                }
     480            }
     481        }
     482
     483        /// <summary>
     484        /// This callback only get fired, when the publisher didn't sent a response on the register message.
     485        /// </summary>
     486        /// <param name="state"></param>
     487        private void OnTimeoutRegisteringAccepted(object state)
     488        {
     489            GuiLogMessage("TIMEOUT: Waiting for registering accepted message from publisher!", NotificationLevel.Warning);
     490            // TODO: anything
     491        }
     492
     493        /// <summary>
     494        /// This callback only get fired, when the publisher didn't sent a response on the ping message.
     495        /// </summary>
     496        /// <param name="state"></param>
     497        private void OnTimeoutPublishersPong(object state)
     498        {
     499            GuiLogMessage("Publisher didn't answer on Ping in the given time span!", NotificationLevel.Warning);
     500            timeoutForPublishersPong.Dispose();
     501            timeoutForPublishersPong = null;
     502            // try to get an active publisher and re-register
     503            CheckPublisherAvailability();
     504        }
     505
     506        /// <summary>
     507        /// Will stop all timers, so Subscriber ends with sending
     508        /// Register-, Alive- and Pong-messages. Furthermore an
     509        /// unregister message will be send to the publisher
     510        /// </summary>
     511        private void StopActiveWork()
     512        {
     513            this.bolStopped = true;
     514            if(actualPublisher != null)
     515                SendMessage(actualPublisher,PubSubMessageType.Unregister);
     516
     517            #region stopping all timers, if they are still active
     518            if (this.timerSendingAliveMsg != null)
     519            {
     520                this.timerSendingAliveMsg.Dispose();
     521                this.timerSendingAliveMsg = null;
     522            }
     523            if (this.timerRegisteringNotPossible != null)
     524            {
     525                this.timerRegisteringNotPossible.Dispose();
     526                this.timerRegisteringNotPossible = null;
     527            }
     528            if (this.timerCheckPubAvailability != null)
     529            {
     530                this.timerCheckPubAvailability.Dispose();
     531                this.timerCheckPubAvailability = null;
     532            }
     533            if (this.timeoutForPublishersRegAccept != null)
     534            {
     535                this.timeoutForPublishersRegAccept.Dispose();
     536                this.timeoutForPublishersRegAccept = null;
     537            }
     538            if (this.timeoutForPublishersPong != null)
     539            {
     540                this.timeoutForPublishersPong.Dispose();
     541                this.timeoutForPublishersPong = null;
     542            }
     543            #endregion
     544        }
    375545        #endregion
    376546    }
    377 
    378 
    379547}
  • trunk/CrypPlugins/PeerToPeerSubscriber/P2PSubscriberSettings.cs

    r836 r862  
    1313    public class P2PSubscriberSettings : ISettings
    1414    {
     15        public event TaskPaneAttributeChangedHandler TaskPaneAttributeChanged;
    1516        private bool hasChanges = false;
    1617        private P2PSubscriber p2pSubscriber;
     
    3536            {
    3637            this.p2pSubscriber = p2pSubscriber;
     38            if (TaskPaneAttributeChanged != null)
     39            {
     40                TaskPaneAttributeChanged(this, new TaskPaneAttributeChangedEventArgs(new TaskPaneAttribteContainer("BtnSolutionFound", Visibility.Collapsed)));
     41                TaskPaneAttributeChanged(this, new TaskPaneAttributeChangedEventArgs(new TaskPaneAttribteContainer("BtnUnregister", Visibility.Collapsed)));
     42                TaskPaneAttributeChanged(this, new TaskPaneAttributeChangedEventArgs(new TaskPaneAttribteContainer("BtnRegister", Visibility.Visible)));
     43            }
    3744            }
    3845
    39         private string sTaskName = "NewCompTask";
    40         [TaskPane("Task Name", "Choose the name of a published computational task", null, 0, false, DisplayLevel.Beginner, ControlType.TextBox)]
    41         public string TaskName
     46        private string sTopic = "NewTopic";
     47        [TaskPane("Topic Name", "Choose a topic name with which this subscriber shall be registered.", null, 0, false, DisplayLevel.Beginner, ControlType.TextBox)]
     48        public string TopicName
    4249        {
    43             get { return this.sTaskName; }
     50            get { return this.sTopic; }
    4451            set
    4552            {
    46                 if (this.sTaskName != value && value != String.Empty && value != null)
     53                if (this.sTopic != value && value != String.Empty && value != null)
    4754                {
    48                     this.sTaskName = value;
     55                    this.sTopic = value;
    4956                    HasChanges = true;
    50                     OnPropertyChanged(TaskName);
     57                    OnPropertyChanged(TopicName);
    5158                }
    5259            }
    5360        }
     61
     62        /* FOR TESTING ISSUES */
     63        [TaskPane("Unregister", "Click here to Unregister the publisher from all registered subscribers!", "Control region", 0, true, DisplayLevel.Beginner, ControlType.Button)]
     64        public void BtnUnregister()
     65        {
     66            TaskPaneAttributeChanged(this, new TaskPaneAttributeChangedEventArgs(new TaskPaneAttribteContainer("BtnSolutionFound", Visibility.Collapsed)));
     67            TaskPaneAttributeChanged(this, new TaskPaneAttributeChangedEventArgs(new TaskPaneAttribteContainer("BtnUnregister", Visibility.Collapsed)));
     68            TaskPaneAttributeChanged(this, new TaskPaneAttributeChangedEventArgs(new TaskPaneAttribteContainer("BtnRegister", Visibility.Visible)));
     69            OnPropertyChanged("BtnUnregister");
     70        }
     71        [TaskPane("Register", "Click here to Register the publisher pro-active with all formely registered subscribers!", "Control region", 1, true, DisplayLevel.Beginner, ControlType.Button)]
     72        public void BtnRegister()
     73        {
     74            TaskPaneAttributeChanged(this, new TaskPaneAttributeChangedEventArgs(new TaskPaneAttribteContainer("BtnSolutionFound", Visibility.Visible)));
     75            TaskPaneAttributeChanged(this, new TaskPaneAttributeChangedEventArgs(new TaskPaneAttribteContainer("BtnRegister", Visibility.Collapsed)));
     76            TaskPaneAttributeChanged(this, new TaskPaneAttributeChangedEventArgs(new TaskPaneAttribteContainer("BtnUnregister", Visibility.Visible)));
     77            OnPropertyChanged("BtnRegister");
     78        }
     79
     80        [TaskPane("Solution found", "TESTING: Emulate solution-found-case!", "Control region", 2, true, DisplayLevel.Beginner, ControlType.Button)]
     81        public void BtnSolutionFound()
     82        {
     83            TaskPaneAttributeChanged(this, new TaskPaneAttributeChangedEventArgs(new TaskPaneAttribteContainer("BtnSolutionFound", Visibility.Collapsed)));
     84            TaskPaneAttributeChanged(this, new TaskPaneAttributeChangedEventArgs(new TaskPaneAttribteContainer("BtnUnregister", Visibility.Collapsed)));
     85            TaskPaneAttributeChanged(this, new TaskPaneAttributeChangedEventArgs(new TaskPaneAttribteContainer("BtnRegister", Visibility.Visible)));
     86            OnPropertyChanged("BtnSolutionFound");
     87        }
     88        /* FOR TESTING ISSUES */
    5489
    5590        private int checkPublishersAvailability = 60;
     
    72107        }
    73108
    74         private int publishersReplyTimespan = 10;
    75         [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, 10, 60)]
     109        private int publishersReplyTimespan = 2;
     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)]
    76111        public int PublishersReplyTimespan
    77112        {
Note: See TracChangeset for help on using the changeset viewer.