Dear visitor, thanks for stopping by! If you want, you can follow all updates on Snowball.be via RSS. You can also follow me on Twitter or Facebook. More interesting posts from other Microsoft Regional Directors can be found at The Region.
Gill Cleeren     .net | Silverlight | Silverlight Advent Calendar | sl4     December 20, 2009    

Services and data access are the focus of the book I’m writing (more very very soon!). Working with services to get data into a Silverlight application is so vital, it should be code that’s known by every Silverlight developer by heart. Working with duplex bindings is somewhat more complicated. However, there are situations in which duplex communication is really necessary. Think of the typical example: a stock application that should send stock updates to the client without the client requesting for an update.

Duplex communications are possible with WCF. They “seem” initiated by the server: the service will send updates without the client requests the service to do so. This way, the client can receive updates whenever new information is available on the server (new stock info that becomes available) and act accordingly. I put seem between quotes. The reason for that is that a duplex binding is in fact still a normal request/receive process. Initially, the client has to do a request to the service and from then on, the service can send its updates to the client.

In the example I have created for this post, I created an application that posts updates about snow throughout Belgium (while writing this article, it has snowed quite a lot in Belgium, so that’s where the inspiration came from and Tienen is where I live :) ). Below is a screenshot.

image

Of course, you’re here to learn something and see some code, right? No problem! Let’s first focus on the service. For the data exchange, I created a small type called SnowUpdate.

public class SnowUpdate
{
    public string Location { get; set; }
    public double centimeter { get; set; }
}

One very important thing that we need to do, is adding a reference to an assembly available in the Silverlight SDK called System.Service.PollingDuplex.dll. By default, it’s installed in C:\Program Files (x86)\Microsoft SDKs\Silverlight\v4.0\Libraries\Server. Add a reference to this assembly. (Note the x86, that’s because I’m running 64bit).

The contract of the service makes it clear that we are working with a duplex service. There are some special things to note in this code. As you can see, two interfaces are defined here. The first one is the regular contract, the second one is what’s called the callback contract and defines the contract for the call to the client.

Also note that both OperationContracts have IsOneWay set to true. For the Connect method, we’re actually saying: a client can call Connect to make itself known to the service but it expects no response, hence the IsOneWay.

[ServiceContract(Namespace = "Silverlight", CallbackContract = typeof(ISnowServiceClient))]
public interface ISnowService
{
    [OperationContract(IsOneWay = true)]
    void Connect();
}
 
[ServiceContract]
public interface ISnowServiceClient
{
    [OperationContract(IsOneWay = true)]
    void SendSnowUpdate(SnowUpdate snowUpdate);
}

In the service implementation, I have created a Timer, which will periodically send a new message to the client. The OperationContext.Current.GetCallbackChannel gives us access to the callback channel which we can use to send messages to the client side. On a tick of the Timer, we’re sending a message.

private ISnowServiceClient client;
private Timer timer;
 
public void Connect()
{
    client = OperationContext.Current.GetCallbackChannel<ISnowServiceClient>();
    timer = new Timer(new TimerCallback(TimerTick), null, 500, 5000);
}
 
void TimerTick(object state)
{
    try
    {
        if (client != null)
        {
            client.SendSnowUpdate(GetLatestUpdate());
        }
    }
    catch (Exception)
    {
 
        client = null;
        timer.Dispose();
    }
}

With that, the service code is done, but it does require some specific configuration code to work. Take a look at the sample for this code. We can now look at the client code. The process to add a service reference is exactly the same, although you’ll notice that the ServiceReferences.clientconfig file remains empty (which it does not when referencing a normal service). Therefore, the code that we need to write is somewhat more complex: we have to create the binding and the address from code and pass this along with the proxy instantiation. Below you can see the client-side code.

private void UserControl_Loaded(object sender, RoutedEventArgs e)
{
  EndpointAddress address = new EndpointAddress("http://localhost:59485/SnowService.svc");
 
  CustomBinding binding = new CustomBinding(
    new PollingDuplexBindingElement(),
    new BinaryMessageEncodingBindingElement(),
    new HttpTransportBindingElement());
  
  client = new SLDuplexSnow.SnowService.SnowServiceClient(binding, address);
 
  client.SendSnowUpdateReceived += 
    new EventHandler<SLDuplexSnow.SnowService.SendSnowUpdateReceivedEventArgs>
     (client_SendSnowUpdateReceived);
    client.ConnectAsync();
}
 
void client_SendSnowUpdateReceived(object sender, 
  SLDuplexSnow.SnowService.SendSnowUpdateReceivedEventArgs e)
{
    SnowDetailsGrid.DataContext = e.snowUpdate;
}

Note that we are calling ConnectAsync to let the service know about the client so it can send updates to it BUT we are handing SnowUpdateReceived events.

NOTE: This sample is written for Silverlight 3/VS2008. At this point, I have issues with VS2010 when generating the client proxy with SL4/VS2010 when using a duplex service.

The complete code can be downloaded here: SLDuplex.zip (111.91 KB)

  Posted on: Monday, December 21, 2009 12:38:33 AM (Romance Standard Time, UTC+01:00)   |   Comments [4]
         
Monday, December 21, 2009 3:08:53 PM (Romance Standard Time, UTC+01:00)
Gill,
Thanks for the very interesting article. I've only started on the .net programming journey, and am getting into the Silverlight/WPF area more and more. I like your implementation of the duplex service and will study it a bit more when I'm able. I also look forward to reading more of your article (past and present). Good job.
David Y
Tuesday, December 22, 2009 8:43:49 PM (Romance Standard Time, UTC+01:00)
The download contains SL4/VS2010 project files. Could you provide the SL3/VS2008 project files?
Joel Lucsy
Tuesday, December 22, 2009 9:08:29 PM (Romance Standard Time, UTC+01:00)
Sorry, don't have it. You can however create a new VS2008 project and paste in the files, as the code is entirely the same.
Tuesday, December 22, 2009 9:09:16 PM (Romance Standard Time, UTC+01:00)
@David, thanks for visiting, 2 more articles are coming in this series. Enjoy!
Comments are closed.
9/2/2010   9:33:26 PM