Internals of Indigo (CTS467)

Some random notes that I picked up during this massive-info talk (again 9+)

Messaging layer will be used by lots of Microsoft products like BizTalk or ADO.NET. It’s the lower layer of Indigo and involves getting data around.
Indigo message are CLR representations of the SOAP infoset. The Indigo message is very flexible and you can create your own version of it.
The listener starts listening for an incoming channel (not message). The corresponding method AcceptChannel() describes this pretty well. After a client hooks up a channel, the service can receive the messages through the service-side end of the channel.
So, moving Indigo infosets is a socket-like mechanism (Steve even called it “WinSock for XML”). These channels have factories with a generic method CreateListener<T>(). Similarly the client has a channel factory that spits out channel with CreateChannel<T>.

The transports do the actual transport of messages flowing through the channels. These are pretty much decoupled from the channels to allow for a choice in transport without having to rearrange your channel(s). Each channel has an encoder to read the wire format of the message.
Dual channels allow you to do full duplex communication between client and service. Protocol channels often insert information in the header of the message, but can also send extra messages over the channel even though these are not intended for your application.

This is what a service might look like. It demonstrates the various constructs that are used to open listeners and channels and finally accepts messages and sends back replies. You will probably not write such code yourself, because Indigo will perform most of this for you.

class ServerSide
{
  IListenerFactory = null;

  public void StartService()
  {
    listenerFactory = CreateListenerFactoryStack();

    // Checks compatibility of listener
    listenerFactory.Open();

    IListener<IReplyChannel> lst = listenerFactory.CreateListener<IReplyChannel>();
    lst.BeginAcceptChannel(new AsyncCallback(handlecHannel), lst);
  }

 
private static IListenerFactory CreateListenerFactoryStack()
  {
    HttpListenerFactory hlf = new HttpListenerFactory();
    hlf.AuthenticationScheme = System.Net.AuthenticationSchemes.Anonymous;
    hlf.SetUri(new Uri(“
http://localhost/myep“));
  
    // Stack your listeners
    ReliableListernerFactory rlf = new ReliableListenerFactory();
    rlf.MaxRetryCount = 8;
    rlf.InnerListenerFactory = hlf;

    // Default UTF-8 for message encoding
    // hlf.MessageEncoderFactory
    // hlf.MessageVersion sets soap version used
    return rlf;
  }

  void HandleChannel(IAsyncResult
  {
    IListener<IReplyChannel> lst = asyncResult.AsyncState as IListener<IReplyChannel>;
    IReplyChannel rpc lst.EndAcceptChannel(AsyncResult);
    rpc.Open();
    rpc.BeginReceiveRequest(new AsyncCallback(HandleRequest), rpc);
    lst.BeginAcceptChannel(new AsyncCallback(HandleChannel), lst);
  }

  void HandleRequest(IAsyncResult asyncResult)
  {
    IReplyChannel rpc = asyncResult.AsyncState as IReplyChannel;
    IRequestContext rqx = rpc.EndReceiveRequest(asyncResult);
    Message request = rqx.RequestMessage;
 
    // Do something with request. et cetera
    Message reply = Message.CreateMessage(“urn:boo”, “boo”);
    rqx.Reply(reply);
  }

  public void StopService { }
}

In the service model layer you program directly against indigo with typed proxies at the client and dispatchers at the service. The proxy lives at the top of a channel stack (in which you can insert your own channels), giving you a separation between the two.
Inside the proxy there are ProxyBehaviors and ProxyOperations. The first can change the passing messages on the operations that are performed.
The dispatcher at the service behaves pretty much the same, having DispatchBehavior and DispatchOperation.

The Indigo build strategy is to turn code+config into a description which can be turned into metadata or runtime object like channels. Indigo first passes the config and creates the description, then reflects the code and adds more details to the description. Vice Versa it takes a look at the description and can generate code from it.

Finally the runtime needs to be wired up. A ServiceHost<T> has both a description and a runtime (channel and dispatcher and instances of your type).

The ordered list of binding elements are used to build the channel stack with a transport channel at the bottom. The top binding element is asked to create a stack.

Advertisements
This entry was posted in Uncategorized. Bookmark the permalink.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s