Silverlight Feeds - All your Silverlight feeds in one place.

Sponsors

Friday, October 23, 2009

Handling duplicated connections on Polling Duplex

by Andrea Boschin via Silverlight & XAML Playground on 10/23/2009 12:46:00 AM

The last tip I would like to propose is a tecnique to avoid a single client machine connect multiple times to the same polling server. This may be the case when the user starts two or more instances of the browser or open the same page in multiple tabs. In this scenario may be unuseful to have every page connected to the server.

In Silverlight 3.0 there is a way to check when a plugin has been loaded many times. When you try to create a LocalReceiver with the same name from two instances you get an exception because they cannot share the same name. So using a LocalReceiver you can check if another browser is open.

   1: public override void Start()
   2: {
   3:     LocalMessageReceiver receiver = this.CreateReceiver();
   4:  
   5:     if (receiver != null)
   6:     {}  // receiver created: I'm the master...
   7:     else
   8:     {}  // cannot create receiver: I'm a slave...
   9: }
  10:  
  11: private LocalMessageReceiver CreateReceiver()
  12: {
  13:     try
  14:     {
  15:         LocalMessageReceiver receiver = new LocalMessageReceiver("PollingReceiver");
  16:         receiver.Listen();
  17:         return receiver;
  18:     }
  19:     catch(ListenFailedException)
  20:     {
  21:         return null;
  22:     }
  23: }

 

Checking the presence of another instance is only half of the work to do. When you detect you are a slave in the machine you need to avoid connecting - slave does nothing because a master already exists - and probably you have to change the user interface to let the user know that there is another instance running.

In my application I need to check the presence of the master every few seconds to let a slave becoming a master. To do this I've created two classes MasterPollingClientCode  SlavePollingClientCore implementing the same interface IPollingClientCore. The first class connect to the server and the other class simply does nothing.

   1: public override void Start()
   2: {
   3:     LocalMessageReceiver receiver = this.CreateReceiver();
   4:  
   5:     if (receiver != null)
   6:         this.Core = new MasterPollingClientCore(this.SessionId, this.EndPoint, receiver);
   7:     else
   8:         this.Core = new SlavePollingClientCore(this.LocalId, 
                          new LocalMessageSender("PollingSender" + this.LocalId.ToString()));
   9:  
  10:     this.Core.AlarmReceived += new EventHandler<NotifyAlarmReceivedEventArgs>(Core_AlarmReceived);
  11:     this.Core.Connected += new EventHandler(Core_Connected);
  12:     this.Core.Disconnected += new EventHandler(Core_Disconnected);
  13:     this.Core.Fault += new EventHandler<PollingFaultEventArgs>(Core_Fault);
  14:     this.Core.Start();
  15:     base.Start();
  16: }
 

The container class, then starts a thread. This thread try to create a new LocalReceiver and when it is able to get an instance it change the core class from slave to master and connect to the server. This way the client is always connected to the server with alwasy one simple connection:

   1: protected override void ThreadProc()
   2:     {
   3:         Debug.WriteLine("ThreadProc");
   4:  
   5:         while(WaitHandle.WaitTimeout == WaitHandle.WaitAny(this.ExitHandles, 5000))
   6:         {
   7:             if (this.Mode != PollingClientMode.Master)
   8:             {
   9:                 Deployment.Current.Dispatcher.BeginInvoke(
  10:                     ()=> this.TryConvertToMaster());
  11:             }
  12:         }
  13:     }
  14:  
  15:     /// <summary>
  16:     /// Tries the convert to master.
  17:     /// </summary>
  18:     private void TryConvertToMaster()
  19:     {
  20:         Debug.WriteLine("TryConvertToMaster");
  21:  
  22:         LocalMessageReceiver receiver = this.CreateReceiver();
  23:  
  24:         if (receiver != null)
  25:         {
  26:             Debug.WriteLine("created");
  27:  
  28:             // detach all
  29:             this.Core.Stop();
  30:             this.Core.AlarmReceived -= new EventHandler<NotifyAlarmReceivedEventArgs>(Core_AlarmReceived);
  31:             this.Core.Connected -= new EventHandler(Core_Connected);
  32:             this.Core.Disconnected -= new EventHandler(Core_Disconnected);
  33:             this.Core.Fault -= new EventHandler<PollingFaultEventArgs>(Core_Fault);
  34:             // create new core
  35:             this.Core = new MasterPollingClientCore(this.SessionId, this.EndPoint, receiver);
  36:             // attach all
  37:             this.Core.AlarmReceived += new EventHandler<NotifyAlarmReceivedEventArgs>(Core_AlarmReceived);
  38:             this.Core.Connected += new EventHandler(Core_Connected);
  39:             this.Core.Disconnected += new EventHandler(Core_Disconnected);
  40:             this.Core.Fault += new EventHandler<PollingFaultEventArgs>(Core_Fault);
  41:             this.Core.Start();
  42:         }
  43:     }
 
 

If you are brave you can try to implement a communication between Slave and Master using a LocalSender. Using the code I provider this task cannot be too hard.

Good Work

email it!bookmark it!digg it!

Original Post: Handling duplicated connections on Polling Duplex

Subscribe

New Feed

Product Spotlight

Recently Updated Sources

Legal Note

The content of the postings is owned by the respective author. Silverlight Feeds is not responsible for the contents of the postings. This site is automatically generated and cannot be reviewed for abusive content. If you find abusive content on Silverlight Feeds, please contact us. Designated trademarks and brands are the property of their respective owners. All rights reserved.

Advertise with us