I recently delivered an 'Introducing WCF' presentation to one of my clients and wanted to find and create interesting demonstrations that didn't make WCF look totally boring next to the WPF stuff I had lined up for the session directly afterwards.
I came across Shy Cohen
's cool demonstration of reliable messaging that breaks an image into chunks and sends the chunks to a WCF service which rebuilds the image. However, he also created a new channel for the client that would randomly drop messages so the image would arrive incomplete. Naturally, you could then turn on reliable messaging and the image would arrive just fine despite
This was perfect, visual and a great demonstration of reliable messaging. However, I thought it could be pushed a bit harder and include a demonstration of the reliable ordering
This is what it looks like and, yes, of course I used WPF :).
As you can see, the some of the messages have failed to be delivered (2 out of 25) and some of those that have arrived have done so in the wrong order. Now, if we turn on reliable messaging in both the client and server's app.config file...
Now, all the images have arrived but in a bit of a jumble. So let's turn on ordered messages too...
Hooray! Our messages have arrived intact and in the correct order.
How it works
It actually took me a while to work out how I would achieve the jumbling of messages. After all, messages were unlikely to get jumbled up over the wire when both the client and server are on the same machine. Clearly, I was going to have to intervene.
Since my sends are synchronous (blocking call until the individual message has been delivered) I use a ThreadPool thread for each send and then put a random sleep somewhere in the send to jumble up the messages. Only problem is that the ThreadPool doesn't guarantee that WorkItems will be processed in the order they were delivered so there was every chance that my messages would arrive into the WS-ReliableMessaging mechanisms in the wrong order to start with.
I needed to ensure that messages made it through the majority of the channel and binding stack in the correct order, but then got jumbled at the very last minute with my random sleep (up to 250ms). Once I realised this it was easy enough to adjust the custom binding Shy used in his demo and add a little bit of synchronisation between MessageInterceptor and the calling code (admittedly not best practice but then how often do you wanna jumble messages?).
Why not check out the code for yourself:
Download the source
Please bear in mind that the jumbling and dropping of messages is random so sometimes they all arrive just fine and in the correct order.
20 Dec 2007
» Next Post:
Automatic Class Tester now on Codeplex
« Previous Post:
Reason 10. Validation
Comments are closed for this post.
19 Jan 2008
06 Jun 2008
Just what I was looking for ;)
09 Dec 2009
Nice demo!!! Helps a lot!
03 Jun 2010
Very nice demo!
I wonder which benefits reliable messaging really provides in real world applications? Your example uses one-way contracts and reliable session to ensure the delivery in the right order. This order is given by order of service calls in the client. These calls are queued in the thread pool and there are probably more than one thread running at the same time, right? Well, Windows schedules thread with a round robin algorithm, that means threads are executed in another order as expected. I just enforced that in your code with the following lines of code:
ThreadPool.QueueUserWorkItem(new WaitCallback(delegate(object state)
Random randomizer = new Random((int)DateTime.Now.Ticks);
Your code does the same as when let svcutil.exe generate the proxy with the async-pattern. With the async-pattern the wcf-call gets queued and executed when a new thread is available with exact the same problem, right?
Your example shows the power of reliable messaging very well. What I think about reliable messaging is that it solves a problem which does not exists in a real world application, because nobody will write such code for productive usage (hopefully). I would write it by sending a chunk, waiting for response, sending next chunk, waiting for response, and so on. And can a request get lost without to get a response? No, I think not when not using one-way contracts. In minimum you will get an exception as response. I wonder also why traditional web-application does not suffer with reliable problems. I think it does not really exist when using a strict request-reply message exchange pattern.
I’m trying to understand the motivations for using reliable messaging and I read a lot of them in the past few weeks (including your great example). Maybe, someday I will understand it…