Published
Wednesday, March 30, 2005 3:40 PM
by
mtaulty
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.