NGWS SDK Documentation  

This is preliminary documentation and subject to change.
To comment on this topic, please send us email at ngwssdk@microsoft.com. Thanks!

Architecture

Figure 2: Contexts and Base Remoting Infrastructure Architecture.

Server side startup

When the server application is first started it performs a number of activities. One of these is to register the server channels. The server channel can use this opportunity to start to listen for requests on the protocols they were designed for. One of the aspects of registering the server channels, is when a server object reference returned to the caller as the result of a method call, an ObjRef is created. The ObjRef is populated with the channel data of the registered channels. This allows the caller to make method calls on the server object using the available server protocols if those protocols are also available on the caller. Channels are registered via ChannelServices.RegisterChannel.

In order for incoming calls to reach the server objects, the inbound object identifier (URI) needs to be resolved to the real server object and the first message sink that can be used to communicate with the real server object. Remoting Services uses the entries in the identity table in order to find these items. Entries are place in the identity table when objects are marshaled. Objects are marshaled when server object references are returned, as the result of a method call. Objects can also be marshaled for well known objects.

Well known objects can use well known names and register these into the identity table.

There are three types of well known objects:

When context-bound objects are created a matching context is found or create that meet the context property requirements for the object. See the context section for further details.

When a server object is marshaled the server object sink chain, which leads to the object is built. The stack builder sink is the last sink in the server object chain and communicates with the server object directly. The stack builder sink is provided by the remoting infrastructure. When a server object that is context-bound is marshaled, the reference to the context in which the object was created is stored in the entry in the identity table.

When inbound calls arrive, they are dispatched on the server object. The identity table provides the URI to object, context and message sink chain mapping.

Client side startup

The client application is first started it performs a number of activities. One of these is to register the client channels. One of the aspects of registering the client channels, is when a server object reference returned to the caller as the result of a method call, an ObjRef is created. The ObjRef is populated with the channel data of the registered channels. This allows the caller to make method calls on the server object using the available server protocols if those protocols are also available on the caller. Channels are registered via ChannelServices.RegisterChannel.

Proxies

The Transparent proxy provides the same class / type by exposing the remote object instance methods and fields. It forwards calls on the proxy to the real remote object instance. The caller is provided with the illusion that the remote instance is local. An explicit check can still be made to determine if the object reference is to a proxy by calling System.Remoting.IsTransparentProxy and passing in the object reference. See the System.Remoting package for details.

Client side Explicit – GetObject

A client obtains a proxy by making an explicit call to Connect. This is shown in the code fragment below:

Foo oFoo = (Foo)Activator.GetObject(
                             typeof(Foo),
                             ”http://store/cart/Foo”);
int ret = Foo.Baz(1, 2.3, “Zap”);

Connect uses the URL to determine whether a proxy already exists for the URL endpoint by performing a lookup in the client side identity table and using the URI (the non channel specific portion of the URL) as the key. If the proxy already exists it is returned to the caller. If no proxy exists then one is created. Creating a proxy involves finding a channel, which supports delivering messages to the URL endpoint. This resolution is performed through ChannelServices and the IChannel interface on the channel. If the channel determines that it is capable of delivering messages it will return a message sink to RemotingServices. RemotingServices then creates the proxy using the metadata of the runtime type / class. The proxy holds references to the first envoy sink chain and channel message sink.

When calls are made on the proxy, the last sink in the envoy chain (which is an infrastructure provided sink) will find the current context on the current thread and call through the client context sink chain.

The last sink the client context sink chain will use the identity table and call the channel sink. The client context sink chain is build by RemotingServices from the context properties of the caller objects context.

Marshaling method parameters

When a method call occurs on the transparent proxy, a message object is generated by the proxy and passed to the first sink in the message sink chain. The message object provides access to the call parameters, method signature, method name, and the destination URI. Access is provided via the IMessage and IMethodCallMessage interfaces. The stack is walked to provide the call parameters.

Message Sink

Message Sinks provide an extensibility mechanism for base remoting. The Message Channel, which delivers messages to the destination, appears as a Message Sink and exposes the IMessageSink interface. Message Sinks can forward the incoming message to another message sink, transform the message or generate a new message. Examples of Messages Sinks are Message Channels, Stack Builder sinks, Debugging sinks, Security sinks and Synchronization sinks. Message Sinks can be composed into a Message Sink chain, with messages being passed through the Message Sink chain.

Message Channel

The source and target Message Channels provide a virtual Message Channel between the source and target. The virtual Message Channel receives messages into the source Channel and delivers the messages into target Message Channel. The virtual Message Channel serializes the message into an appropriate form when transmitting from the source to the target.

Serializing Messages

Serialization is the process of converting a graph of objects, located in memory, into a linear sequence of bytes. That sequence of bytes can be sent elsewhere (for example, to a remote computer) and deserialized, thereby making an exact clone in that remote memory of the original graph of objects. The NGWS runtime Serialization services are located in the System.Serialization package.

Dispatching method calls on to the target object

The target Channel deserializes the message into a Message object. It performs a lookup in the Identity table using the URI in the Message object to find the target object and the first Message Sink in the target Message Sink chain. The Message Channel sends the message to the first Message Sink in the chain. The last Message Sink in the chain is the Stack Builder sink. The Stack Builder sink converts the Message Object into a stack frame and makes the method call on the target object. When the method call returns, the stack has the return values from the call.

Sending returning values back to the caller

The Stack Builder sink converts return values into a message and sends it to the first message sink in the reply sink chain. The last sink in the reply sink chain is the target channel. The reply message is serialized and returned back to the source channel.

Propagating return values back onto the original stack

The source Message channel deserializes the reply message into a Message object and sends the message to the next reply Message Sink in the chain. The last Message Sink in the reply sink chain propagates the return values to the caller stack. [Implementation note: the last Message Sink in the reply sink chain is the original message created by the proxy, which was sent to the first message sink when the call started. The call unwinds and the proxy returns to the caller.]