Mike Taulty's Blog
Bits and Bytes from Microsoft UK
A slightly different "hello world" for Indigo

Blogs

Mike Taulty's Blog

Elsewhere

Archives

I've started playing with Indigo a little bit. Clemens Vasters has three great posts on the basics of Indigo so I'm not going to reiterate those here but will link to them;

A Weekend With Indigo. Part 1- Simple Messaging

A Weekend With Indigo. Part 2- Fun with Messaging and Explicit Addressing

A Weekend With Indigo. Part 3- Hard-Core Messaging. Duplex Conversations.

As always with technology, I have a strange "bottom up" learning style which is really unproductive as it tends to mean I spend a long time trying to work out what the heck is going on rather than focusing on just getting stuff done. Then again, the "stuff that I have to get done" these days is really more about learning how things work than actually doing anything productive with them :-)

I built a couple of sample Indigo applications with ServiceContract, OperationContract and ServiceHost and that seemed pretty good but I was feeling a bit itchy as to what was going on. With that in mind, I tried to reduce what I had down to its bare essence.

What I was wondering was - what if I just want to write code (no configuration) and have a simple SOAP message sent from A to B over HTTP. How do I do that? Essentially, what is it that's underpinning what's going on when I use Endpoints, Bindings and so on to get this done automatically for me?

Here's the code I came up with. I'm sure it's not the "right" way to do things but I found it informative to play around with it. My "service" code looks like this;

using System;

using System.ServiceModel;

using System.ServiceModel.Channels;

using System.Xml;

 

namespace ConsoleApplication4

{

            class Program

            {

                        static void Main(string[] args)

                        {

                                    HttpListenerFactory factory = new HttpListenerFactory();

 

                                    factory.SetUri(new Uri("http://localhost:5050/simpleService"));

 

                                    factory.Open();

 

                                    IListener<IInputChannel> listener =

                                                factory.CreateListener<IInputChannel>();

 

                                    IInputChannel channel = listener.AcceptChannel();

 

                                    channel.Open();

 

                                    Message message = channel.Receive();

 

                                    DumpMessageToConsole(message);

 

                                    message.Close();

                                    channel.Close();

                                    factory.Close();

                        }

                        private static void DumpMessageToConsole(Message m)

                        {

                                    XmlTextWriter writer = new XmlTextWriter(Console.Out);

                                    writer.Formatting = Formatting.Indented;

 

                                    m.WriteMessage(writer);

 

                                    writer.Close();

                        }

            }

}

Normally, you're not going to program this way because one of the big benefits of Indigo is that you don't have to bake into your code specific choices such as HTTP or URI's like this. However, for me it helps the learning process as it does illustrate that somewhere in the infrastructure are a bunch of Listener factories which know how to create channels. Here, we get hold of an IInputChannel and make the call to AcceptChannel which is very much (in my opinion) like the call to Accept on a Socket in that it accepts a new incoming connection which we can then do communication on. Clearly, my code's not really right as it only ever accepts one incoming connection but you get the picture.

 

Once you have a channel, you can use it to receive messages (synchronously, asynchronously) and, here, I just receive the first message synchronously and dump it to the console.

 

On the "sending" or "client" side the code that I ended up with looks like this;

using System;

using System.Xml;

using System.IO;

using System.ServiceModel;

using System.ServiceModel.Channels;

 

namespace ConsoleApplication3

{

            class Program

            {

                        static void Main(string[] args)

                        {

                                    HttpChannelFactory factory = new HttpChannelFactory();

 

                                    factory.Open();

 

                                    IOutputChannel channel = factory.CreateChannel<IOutputChannel>(

                                                "http://localhost:5050/simpleService");

 

                                    channel.Open();

 

                                    StringReader content = new StringReader("<hello>world</hello>");

 

                                    XmlTextReader reader = new XmlTextReader(content);

 

                                    Message message = Message.CreateMessage("urn:someAction",

                                                reader);

 

                                    channel.Send(message);

 

                                    message.Close();

 

                                    channel.Close();

 

                                    factory.Close();

                        }

            }

}

This is a mirror image really of what's happening on the "service side". Here we use the HttpChannelFactory to make an IOutputChannel and we then explicitly create a message and send it down that channel.

 

That's it :-) I've been playing and reading and making some rough notes but I don't quite have the architecture for all this stuff in my head right now but getting to this point has helped me a lot today.

 

 


Posted Wed, Mar 30 2005 3:40 PM by mtaulty