RSS 2.0
# Thursday, July 17, 2008

In the several months I've been procrastinating on the media player remote project, the industry has continued to advance. I just ran across Mirage, a remote control application that appears to target the exact problem I am trying to solve with my little application. But, I'm too cheap to shell out $200 for something I know I can write myself. Let's see if this adds any motivation to the development effort.

Thursday, July 17, 2008 7:00:16 AM (Pacific Standard Time, UTC-08:00)  #    Comments [0] -

# Wednesday, July 09, 2008

Update - The source for this article is available at http://www.cavinconsulting.com/Code/MediaPlayerRemote7a.zip.

The current version of the Smart Client Software Factory comes with a clever WCF service proxy recipe called the Disconnected Service Agent recipe. This recipe is a much nicer version of the webservice proxy shipped with the prior version of the toolkit. One of the nice parts of this recipe is the automatic online/offline detection capabilities. At its root, the recipe uses a RequestManager to queue up and dispatch webservice requests. Attached to the RequestManager is an IConnectionMonitor. By default, this connection monitor automatically keeps track of a client's connection status.

Unfortunately, this only determines if a client has a connection to the Internet, not whether the client can actually call the webservice of interest. What we want is to make sure the client is really "Online" with respect to the webservice it is calling. There are a couple of ways we can do this. The toolkit allows us to plug in our own service that implements IConnecitionMonitor. We could implement IConnectionMonitor in our own custom service and add an attribute to the ConnectionMonitor tag in the app.config file that would make the framework spin up our own, custom definition of what it means to be "online". That's probably the right way to do things, but I decided to implement a WebserviceMonitor service that simply polls the desired webservice to make sure it is available.

I added IConnectionMonitor.cs to Infrastructure.Interface/Services as an interface with a single, read only property -- IsConnected, and a single event -- ConnectionStatusChanged. Then, I added ConnectionMonitor.cs to Infrastructure.Module/Services as a class that implements both IConnectionMonitor and IBuilderAware:

public class WebserviceMonitor : IWebserviceMonitor, IBuilderAware
{ ... }

The constructor of the class uses the existing IConnectionMonitor as a service dependency:

private IConnectionMonitor _connectionMonitor;
public WebserviceMonitor([ServiceDependency] IConnectionMonitor connectionMonitor)
{
    _connectionMonitor = connectionMonitor;
    _connectionMonitor.ConnectionStatusChanged += new EventHandler(connectionMonitor_ConnectionStatusChanged);
}

The IConnectionMonitor manages whether the machine is online or offline. So, we need to manage the other half (whether we can get to the webservice). So, we implement a member method to answer the question:

private void UpdateConnectedStatus()
{
    bool wasConnected = _connected;
    _connected = _connectionMonitor.IsConnected && WebserviceAvailable();
    if (wasConnected != _connected)
        OnConnectionStatusChanged(_connected);
}

With that, we can call UpdateConnectedStatus on creation as well as any time ConnectionStatusChanged is fired by the connection manager. When we sense a connection change, we fire our own ConnectionStatusChanged event using the built-in event mechanism:

[EventPublication(EventTopicNames.OnlineOfflineUpdate,PublicationScope.Global)]
public event EventHandler<EventArgs<bool>> ConnectionStatusChanged;

But this doesn't solve the problem completely. Why not? The webservice status is only updated in the event of a connection status change as fired by the IConnectionMonitor. So, how do we make sure the webservice status is updated periodically, even if the connection status doesn't change? One solution is to use a thread timer in the service to make periodic calls to the webservice. We can implement this by taking advantage of our IBuilderAware methods:

public void OnBuiltUp(string id)
{
    _connectionCheckTimer = new System.Threading.Timer(new System.Threading.TimerCallback(Tick), null, 0, PingDelay);  
}

public void OnTearingDown()
{
    if (null != _connectionCheckTimer)
    {
        _connectionCheckTimer.Dispose();
        _connectionCheckTimer = null;
    }
}

There are the basic steps for producing a webservice monitor within the SCSF. I'm sure there are better ways of solving the problem, but this one works pretty well for my needs. Of course, subscribing to the service is as easy as getting a reference to the service or subscribing to the global event:

[EventSubscription(EventTopicNames.OnlineOfflineUpdate, ThreadOption.UserInterface)]
public void OnlineOfflineUpdateHandler(object sender, EventArgs<bool> e)
{
    _onlineOfflineLabel.Text = e.Data ? "Online" : "Offline";
}

Hope this helps.

Wednesday, July 09, 2008 3:44:04 AM (Pacific Standard Time, UTC-08:00)  #    Comments [4] -
Windows Media Player
Navigation
Categories
About the author/Disclaimer

Disclaimer
The opinions expressed herein are my own personal opinions and do not represent my employer's view in any way.

© Copyright 2010
Cavin Consulting
Sign In
Statistics
Total Posts: 28
This Year: 0
This Month: 0
This Week: 0
Comments: 4
All Content © 2010, Cavin Consulting
DasBlog theme 'Business' created by Christoph De Baene (delarou)