WCF to the rescue

Published 7 July 8 7:41 PM | William

Although part of the idea below was mine, James Ashley was crucial to helping me figure this out.

Problem:

Without getting into the ghoury details, we have an application that allows users to send messages to large groups of people.  Anyone using a client application that is logged on will get a special notification which they can respond to once a message is sent. So far, Polling has been the bane of our existence.  We're trying to fancy up the UI and Telerik's Winforms controls have helped out a lot, but there's simply no way I've been able to find to have a snappy UI with a lot of really cool looking effects - all the while polling every few seconds.  Until now, I just bit down, and took a walk through multi-threadedville.

 

I wanted to remove the polling.  We had experimented with a few different architectures, but all had the same problem, polling.  So let's say you had 200 users logged on.  In the User's bar, we wanted to show each user and their picture - much the same way IM does.  This app had to work across network boundaries and you couldn't count on being able to use TCP so we had to at least make it work with http.  If you poll every three seconds, to get the latest info on who's logged on and off, rebuilding the list of user's was painful. We resorted to several tricks to determine if a user was already in the list, but all of it was putting lipstick on a pig.

 

Solution:

One of the big things you often hear about with WCF is self-hosting.  I had ignored it for the most part.  But today, I wanted to basically have a Winforms app host one service, and a Windows Service host the other part of the service, having the services talk to each other. The client winforms app would simply talk to the client service, it would never hit the Windows Service directly.

So we built a client service and server service, with a client winforms app hosting the client service and a mock Windows Service (which was simply another winforms app) that hosted the service.

The problem we kept running into is as each client signed on to the system, how could we tell the server svc that they were online?  Dynamically adding endpoints is child's play, but with each winforms app, you could only interact with the ServiceHost - not the service.

We tried using traditional events to no avail - that wasn't a surprise but we figured it's worth a try.  Then James recommended a static event. I was completely skeptical, but alas it worked. 

After looking at Juval's framework though, it became really clear. If we want the services to be able to interact with the hosts, then simply self-host the things.

So we had a method called ReceiveMessage which was called from the service (via a client proxy for the client service).  Here's basically what the client looked like:

public partial class Form1 : Form, IClientService
{
    public Form1()
    {
        InitializeComponent();
    }

    ServiceHost currentHost = null;
    private void btnStartService_Click(object sender, EventArgs e)
    {
        currentHost = new ServiceHost(typeof(Form1));
        try
        {
            currentHost.Open();
            lblServiceStatus.Text = "Started";
        }
        catch (Exception ex)
        {
            lblServiceStatus.Text = ex.Message;
        }
    }

    public string ReceiveMessage(string msg)
    {
        String myMessage = msg;
        MessageBox.Show(myMessage);
        return msg;
    }

....

 

Now, from the Administrative application (which interacted with the service, you could Send a message by doing the following:)

private void btnSend_Click(object sender, EventArgs e)
  {
      proxy = new ClientServiceClient(new NetNamedPipeBinding(), endpoint );
      try
      {
          proxy.ReceiveMessage(rtbMessageText.Text);
      }
      catch (FaultException ex)
      {
          lblServiceStatus.Text = ex.Message;
      }
  }

 

 

ClientServiceClient is a stupid name for a client proxy class, but we were just experimenting - the main thing to note is that it's simply a proxy class for the client service, the same service that's effectively being hosted by the Winforms client.  There's a server method called SendMessage(String msg) which you'd call on the service, which in turn would dynamically add endpoints for each active client , and then send the messages to them.

 

You can easily store all the information for clients you want to send messages to in a List<> or similar structure - or if you need stronger persistence or have different needs, then you can use a database.  Either way the end result is the same - loop through all the clients, add an endpoint for each one, loop through each and call the method you want.

I'm having trouble getting to my ftp server from where i'm at, but I'll post the code when I can. In the meantime, if you're interested, just drop me a line.

Search

This Blog

Tags

Community

Archives

News

  • William G Ryan William Ryan Bill Ryan W.G. Ryan Charles Mark Carroll Charles M Carroll
    My Blog Juice Microsoft MVP
    Bill Ryan W.G. Ryan William Ryan
    Cuckooz' MySpace Page View Bill Ryan's profile on LinkedIn
    My Profile on Twitter
    Please note that this is my personal blog and the opinions expressed are my own. Also, comment moderation is about one of the least important things in my life so please keep that in mind. I can't vouch for the authenticity of any of the posters so please don't hold me accountable. And whatever you do, don't pretend to be Noted Option Strict Off expert and AspFriend Charles Mark Carroll when you post. Doing so will lead him to become apoplectic and write absurd accusatory posts about me that are as coherent and thought out as they are factually correct. He does a stellar job proving his reputation is well deserved and he doesn't need any help from you making himself look foolish. If I have to listen to him banging his spoon off of his high chair one more time, I'm going to burst into flames so please don't make that happen!

    My other sites

    Cool Stuff

    Book Stuff

    Security

    ORM

    Data Access

    Funny Stuff

    Compact Framework Stuff

    Web Casts

    My KnowledgeBase Articles

    My MVP Profile

    Design Patterns

    Performance

    Debugging

    Remoting

    My Fellow Authors

    My Books

    LINQ

    Misc

    Speech

    Syndication

    Email Notifications