Microsoft. NET Remoting: technical overview

Source: Internet
Author: User
Document directory
  • HTTP Channel
  • TCP Channel
Introduction

Microsoft. NET Remoting provides a framework that allows an object to interact with another object through an application domain. This framework provides a variety of services, including activation and storage support, and communication channels responsible for message transmission with remote applications. The formatter is used to encode and decode a message before it is transmitted through a channel. Applications can use binary encoding when focusing on performance and XML encoding when interacting with other remote processing frameworks. When a message is transmitted from one application domain to another, all XML encoding uses the SOAP protocol. For security considerations, remote processing provides a large number of hooks, allowing the Security receiver to access messages and serialize streams before the message passes through the channel for transmission.

Generally, without the support of the underlying framework, it is very troublesome to manage the lifetime of remote objects .. NET Remoting provides many alternative survival models that fall into two categories:

  • Client activation object

  • Server activation object

The client activation object is controlled by the lease-based survival manager, which ensures that the object can be recycled when the lease period expires. For server activation objects, developers can select the "single call" mode or "single element" mode.

Remote Object

One of the main purposes of any remote processing framework is to provide the necessary infrastructure to hide the complexity of remote object calling methods and returned results. Any object outside the caller's application domain is considered a remote object even if it is executed on the same computer. In the application domain, the original data type is passed by numerical value, and all objects are passed by reference. Because local object references are valid only in the application domain of the created object, they cannot be passed to remote method calls or returned from remote method calls in this way. All local objects that must span the application domain must be passed by numerical value, and[Serializable]Custom Attributes are marked, otherwise they must be implementedISerializableInterface. When an object is passed as a parameter, the Framework serializes the object and transmits it to the target application domain. The object will be re-constructed in the target application domain. Local objects that cannot be serialized cannot be passed to other application domains, and thus cannot be processed remotely.

FromMarshalByRefObjectExport object. You can change any object to a remote object. When a client activates a remote object, it receives the proxy of the remote object. All operations on the proxy are appropriately reoriented so that the remote processing infrastructure can correctly intercept and forward calls. Although this type of redirection has some impact on the performance, the JIT compiler and execution engine (EE) have been optimized to allow proxies and remote objects to reside in the same application domain, prevent unnecessary performance loss. If the proxy and remote object are not in the same application domain, all method call parameters in the stack will be converted to messages and transmitted to the remote application domain, these messages will be converted to the original stack frame in the remote application domain, and the method call will also be called. The same process is also used when returning results from a method call.

Proxy object

The proxy object is created when the client activates a remote object. As a remote object representative, the proxy object ensures that all calls made to the proxy can be forwarded to the correct remote object instance. To accurately understand how proxy objects work, we need to study them more deeply. When a client activates a remote object, the framework createsTransparentProxyA local instance of the class (this class contains the list of all classes and interface methods of remote objects ). BecauseTransparentProxyClass is registered with CLR during creation, so all method calls on the proxy are intercepted at runtime. In this case, the system checks the call to determine whether it is a valid call to a remote object, and whether the instance of the remote object is in the same application domain as the proxy. If the object is in the same application domain, a simple method call is routed to the actual object. If the object is in different application domainsInvokeMethod to package itIMessageObject and forward itRealProxyClass. Such (or its internal implementation) is responsible for forwarding messages to remote objects.TransparentProxyClass andRealProxyClass is created in the background after the remote object is activated, but onlyTransparentProxyReturn to the client.

To better understand these proxy objects, we need a brief introduction.ObjRef. The activation section contains information aboutObjRef. The following solution briefly describesObjRefAssociation with the two proxies. However, please note that this is only an extremely general description of the process. Based on whether the objects are client-activated objects or server-activated objects, and whether they are single element objects or single call objects, the process is different.

  • The remote object is registered in the application domain of the remote computer. Remote Object is blocked to generateObjRef.ObjRefIt contains all the information required to locate and access remote objects from any location on the network, including the class enhancement name and class hierarchy (parent class) the name of all interfaces implemented by the class, the object URI, and the details of all registered available channels. When receiving a request for a remote object, the remote processing framework uses the object URI to retrieveObjRefInstance.

  • The client callsNewOrActivatorFunction (for exampleCreateInstance) To activate the remote object. For the server activation object, the remote objectTransparentProxyWill be generated in the client application domain and returned to the client, then no remote call is executed. The remote object is activated only when the client calls a method of a remote object. This scheme is obviously not suitable for activating objects on the client, because the client wants the framework to activate objects only when the request is received. When the client calls an activation method, the client creates an activation proxy and uses the URL and object URI as the endpoint to initialize a remote call on the server's remote activator. The remote activator activates the object and thenObjRefFlow to the client, and is unblocked to generate a response to the clientTransparentProxy.
  • Analysis will be made when the mail is canceledObjRefTo extract the method information of the remote object.TransparentProxyAndRealProxyObject. Register with CLRTransparentProxyBefore, after the analysisObjRefContent will be addedTransparentProxy.

TransparentProxyIs an internal class that cannot be replaced or extended, andRealProxyAndObjRefClass is a public class and can be expanded and customized as necessary. BecauseRealProxyClass can process all function calls of remote objects, so it is an ideal method for performing load balancing and other operations. CallInvokeTime, fromRealProxyThe exported class can obtain the server load information in the network and route the call to the appropriate server. Simply requestMessageSinkAnd callSyncProcessMessageOrAsyncProcessMessageTo forward the call to the required remote object. When a call is returnedRemotingServicesClassPropagateMessageToProxyPushes the returned Parameters Back to the stack.

The following code snippet shows how to use the exportedRealProxyClass.

   MyRealProxy proxy = new MyRealProxy(typeof(Foo));
Foo obj = (Foo)proxy.GetTransparentProxy();
int result = obj.CallSomeMethod();

TheTransparentProxyIt can be forwarded to another application domain. When the second client tries to call a method on the proxy, the remote processing framework tries to createMyRealProxyClass, and if the assembly is available, all calls will be routed to this instance. If the Assembly is unavailable, the call is routed to the default remoteRealProxy.

By defaultObjRefAttributeTypeInfo,EnvoyInfoAndChannelInfoProvides substitution and can be easily customizedObjRef. The following code shows how to customize a custom object:

public class ObjRef {
public virtual IRemotingTypeInfo TypeInfo
{
get { return typeInfo;}
set { typeInfo = value;}
}

public virtual IEnvoyInfo EnvoyInfo
{
get { return envoyInfo;}
set { envoyInfo = value;}
}

public virtual IChannelInfo ChannelInfo
{
get { return channelInfo;}
set { channelInfo = value;}
}
}
Channel

A channel is used to transmit messages between remote objects. When a client calls a method on a remote object, parameters related to the call and other details are transmitted to the remote object through the channel. Any result of the call will be returned to the client in the same way. The client can select any channel registered in "server" to achieve communication with remote objects. Therefore, developers can freely select the most suitable channel. Of course, you can also customize any existing channel or create a new channel that uses other communication protocols. The channel selection follows the following rules:

  • Before a remote object can be called, the remote processing framework must register at least one channel. Channel registration must be performed before object registration.

  • The channel is registered by application domain. A process can have multiple application domains. When the process ends, all channels registered by the process are automatically cleared.
  • The channel for listening to the same port is invalid after multiple registrations. Even if the channel is registered by application domain, different application domains on the same computer cannot register a channel that listens on the same port.
  • The client can use any registered channel to communicate with remote objects. When the client tries to connect to a remote object, the remote processing framework ensures that the object is connected to the correct channel. The client callsChannelServiceClassRegisterChannel.

All channels are composedIChannelExport and implement it based on the purpose of the channelIchannelpolicerOrIchannelSender. Most channels implement both the receiver interface and the transmitter interface so that they can communicate in two directions. When the client calls a method on the proxy, the remote processing framework intercepts the call and transfers it toRealProxyClass (or an implementationRealProxyClass.RealProxyForward the message to the Message Receiver for processing. The message receiver is responsible for establishing a connection with the channel for Remote Object Registration, and transmitting messages from the scheduling location to the remote object itself through the channel (in different application domains. After a remote object is activated, the client callsCreateMessageSinkSelect a channel and retrieve the message receiver that can communicate with the remote object.

A confusing aspect of the remote processing framework is the relationship between remote objects and channels. For example, ifSingleCallThe remote object is activated only when it is called. How does this object listen to the client to be connected?

Part of the answer lies in the fact that remote objects do not own their own channels, but share channels. Server applications that host remote objects must register the objects to be exposed through the remote processing framework and the required channels. The registered channel automatically starts listening for customer requests on the specified port. After registering a remote object,ObjRefAnd store it in the table. When a request is uploaded through the channel, the remote processing framework checks the message to determine the target object, and checks the object reference table to locate the reference in the table. If an object reference is found, the framework target object is retrieved from the table or activated when necessary, and then the framework forwards the call to the object. For synchronous calls, the connection from the client is maintained during message calls. Because each client connection is processed on its own thread, a channel can serve multiple clients at the same time.

Security is an important issue when generating business applications. To meet business requirements, developers must add security features such as authorization or encryption to remote method calls. To achieve this goal, developers can customize channels so that they can control the actual message transmission mechanism between remote objects. Before being transmitted to a remote application, all messages must flow throughSecuritySink,TransportSinkAndFormatterSinkAnd the messages will flow through the same receiver in reverse order after being passed to the remote application.

HTTP Channel

The HTTP channel uses the SOAP protocol and remote object to transmit messages. All messages flow through the SOAP formatting program are converted to XML format and serialized. The required SOAP header is also added to the stream. You can also specify a binary formatting program that can generate binary data streams. Then, the data stream is transmitted to the target URI using the HTTP protocol.

TCP Channel

The TCP channel uses the binary formatting program to serialize all messages into binary streams and transmit them to the destination URI using the TCP protocol.

Activate

The remote processing framework supports server activation and client activation of remote objects. Server activation is generally used when remote objects do not need to maintain any state between method calls. Server activation is also applicable when multiple client call methods are located on the same object instance and objects are maintained between function calls. On the other hand, the client activates objects from the client and manages the lifetime of remote objects by using a dedicated lease-based system.

Before accepting access from the client, all remote objects must be registered using the remote processing framework. Object Registration is generally completed by the Host application. The Host application will start and useChannelServicesRegister one or more channels and useRemotingServicesRegister one or more remote objects and wait for termination. Note that registered channels and objects can be used only when they are used to register their process activities. If the process is exited, all channels and Objects registered by the remote processing service are automatically deleted. When registering a remote object in the framework, the following information is required:

  1. The name of the Assembly containing the class.

  2. The type name of the remote object.
  3. The object URI that will be used when the client locates the object.
  4. The object mode required for server activation. This mode can beSingleCall, Or yesSingleton.

Remote objects can be registered in either of the following ways:RegisterWellKnownType, Pass the above information as a parameter; or store the above information in the configuration file, and then callAssumeremotingAnd pass the configuration file name as a parameter. The above two methods have the same functions, so you can use either of them to register remote objects. Of course, the latter method is more convenient, because the configuration file content can be changed without re-compiling the Host application. The following code snippet shows howHelloServiceClass RegisteredSingleCallRemote Object.

RemotingServices.RegisterWellKnownType(
"server",
"Samples.HelloServer",
"SayHello",
WellKnownObjectMode.SingleCall);

Where,“server”Is the Assembly name,HelloServerIs the class name,SayHelloIs the object URI.

After registering a remote object, the framework creates an object reference for the object and extracts the necessary metadata related to the object from the program. Subsequently, this information will be stored in the object reference together with the URI and Assembly name (this object reference will be written into a remote processing framework table for tracking registered remote objects ). Note that the registration process does not instantiate the remote object itself except when the client tries to call a method on the object or activates the object from the client.

Now, any client that knows the object URI can useChannelServicesRegister the channel and callNew,GetObjectOrCreateInstanceActivate the object to obtain a proxy for the object. The following code snippet shows an example of this operation:

      ChannelServices.RegisterChannel(new TCPChannel);
HelloServer obj = (HelloServer)Activator.GetObject(
typeof(Samples.HelloServer), "tcp://localhost:8085/SayHello");

Where,“tcp://localhost:8085/SayHello”Indicates that we want to connect toSayHelloThe remote object of the endpoint. When compiling the client code, the compiler obviously requiresHelloServerClass type information. This information can be provided in one of the following ways:

  • ProvidesHelloServiceThe reference of the Assembly where the class is located.

  • Splits remote objects into implementation and interface classes, and references these interfaces when compiling the client.
  • Use the SOAPSUDS tool to extract the required metadata directly from the endpoint. This tool connects to the provided endpoint, extracts metadata, and generates an assembly or source code that can be used to compile the client.

GetObjectOrNewIt can be used for server activation objects. Note that objects are not instantiated and no network call is actually generated when these two calls are used. The framework obtains sufficient information from metadata to create a proxy, but does not connect to a remote object. A network connection is established only when the client calls a method on the proxy. When a call arrives at the server, the Framework extracts the URI from the message, checks the remote processing framework table to locate the reference of the object matching the URI, and instantiates the object if necessary, and forward the method call to the object. If you register an objectSingleCall, The object will be canceled after the method call is completed. Each time you call a method, a new instance is created.GetObjectAndNewThe only difference between them is that the former allows you to specify a URL as a parameter, while the latter obtains a URL from the configuration.

CreateInstanceOrNewCan be used to activate objects on the client. Both can use constructors with parameters to instantiate objects. The lifetime of the client activation object is controlled by the lease service provided by the remote processing framework. The content of the object lease is described in the next section.

Lease lifetime of Objects

Each application domain contains a lease manager used to manage its lease. All leases are regularly checked to determine whether the lease has expired. If the lease expires, one or more initiators of the lease will be called to give them the opportunity to update the lease. If no initiators are preparing to update the lease, the lease manager deletes the lease and recycles the object as garbage. The lease manager maintains the lease list in the order of the remaining lease time. The shortest time remaining is placed at the top of the list.

Leasing can be achievedILeaseInterface and stores an attribute set to determine the update policy and method. You can also use a call to update the lease. Each time you call a method on a remote object, the lease time is set to the currentLeaseTimeAdd the maximum valueRenewOnCallTime.LeaseTimeThe initiator is required to update the lease. Because we sometimes encounter network instability, we may not find the lease initiator. To ensure that invalid objects are not left on the server, each lease hasSponsorshipTimeout. This value specifies the length of time to wait for the lease initiator to reply before the lease ends. IfSponsershipTimeoutZero,CurrentLeaseTimeWill be used to determine the lease expiration time. IfCurrentLeaseTimeIf the value is zero, the lease will not expire. Configuration or API can be used to replaceInitialLeaseTime,SponsorshipTimeoutAndRenewOnCallTime.

The lease manager maintains a list of initiators whose launch time ranges from large to small storage (they implementISponsorInterface ). When the initiator needs to be called to update the lease time, the lease manager will request to update the lease time from the top of the list to one or more initiators. The initiators at the top of the list indicate that they have requested the longest lease Update time. If the initiator is notSponsorshipTimeOutThe response is deleted from the list. By callingGetLifetimeServiceAnd use the object lease as a parameter to obtain the lease of the object. This call isRemotingServicesClass. If the object is in the application domain, the called parameter is the local reference of the object, and the lease returned is also the local reference of the lease. If the object is remote, the proxy will be passed as a parameter and the rented transparent proxy will be returned to the caller.

The object can provide its own lease and control its own survival. They are replacedMarshalByRefObjectOnInitializeLifetimeServiceMethod to complete this operation, as shown below:

public class Foo : MarshalByRefObject {
public override Object InitializeLifetimeService()
{
ILease lease = (ILease)base.InitializeLifetimeService();
if (lease.CurrentState == LeaseState.Initial) {
lease.InitialLeaseTime = TimeSpan.FromMinutes(1);
lease.SponsorshipTimeout = TimeSpan.FromMinutes(2);
lease.RenewOnCallTime = TimeSpan.FromSeconds(2);
}
return lease;
}
}

The lease attribute can be changed only when the lease is in the initial state.InitializeLifetimeServiceThe implementation usually calls the corresponding methods of the base class to retrieve the existing lease of the remote object. If you have never sent this object before, the returned lease will be in its initial state and you can set the lease attribute. Once an object is blocked, the lease will change from the initial status to the activation status, and ignore any attempts to initialize the lease property (except in one case ). When a remote object is activatedInitializeLifetimeService. Activation call provides a list of lease initiators. When the lease is active, other initiators can be added to the list at any time.

The lease period can be extended in the following ways:

  • The client can callLeaseClassRenewMethod.

  • The lease can request an initiatorRenewal.
  • When the client calls a method on an object,RenewOnCallThe value is automatically updated.

Once the lease expires, its internal status changes from Active to Expired, and no call is made to the initiator, and the object will be recycled as garbage. In general, if the initiators are scattered on the Web or behind a firewall, the remote object calls back the initiators. Therefore, the initiator does not have to be in the same location as the client. As long as the remote object can be accessed, it can be any location on the network.

Using Lease to manage the lifetime of remote objects can be used as an alternative to the reference count, because when the network connection performance is unreliable, the reference count is complex and inefficient. Although some people will insist that the lifetime of remote objects is longer than the required time, leasing reduces the Network busy compared with the reference count and connected customers, it will become a very popular solution.

Summary

To provide a perfect remote processing framework that can meet the needs of most business applications, even if it can be done, it will inevitably be very difficult. Microsoft provides a framework that can be scaled and customized as needed, and takes a key step in the right direction.

Appendix A: Example of remote processing using TCP Channel

This appendix shows how to write a simple "Hello World" Remote Application. The client passes a string to a remote object. The remote object attaches the word "Hi There" to the string and returns the result to the client.

Save this fileServer. cs. Here is the server code:

Using System;
Using System. Runtime. Remoting;
Using System. Runtime. Remoting. Channels. TCP;

Namespace RemotingSamples {
Public class HelloServer: IHello {

Public static int Main (string [] args ){

TCPChannel chan = new tcpchannels (8085 );
ChannelServices. RegisterChannel (chan );
RemotingServices. RegisterWellKnownType (
"Server", "RemotingSamples. HelloServer", "SayHello ",
WellKnownObjectMode. SingleCall );
System. Console. WriteLine ("press <enter> to exit ...");
System. Console. ReadLine ();
Return 0;
}

Public HelloServer ()
{
Console. WriteLine ("HelloServer activated ");
}

~ HelloServer ()
{
Console. WriteLine ("Object cleared ");
}

Public forwardimethyl HelloMethod (forwardimethyl obj)
{
Console. WriteLine ("Hello. HelloMethod: {0}", name );
Return "Hi there" + name;
}
}
}

Save this codeClient. cs:

Using System;
Using System. Runtime. Remoting;
Using System. Runtime. Remoting. Channels. TCP;

Namespace RemotingSamples {
Public class Client
{
Public static int Main (string [] args)
{
TCPChannel chan = new TCPChannel ();
ChannelServices. RegisterChannel (chan );
Forwardimethyl param = new forwardimethyl ();
HelloServer obj = (HelloServer) Activator. GetObject (
Typeof (RemotingSamples. HelloServer), "tcp: // localhost: 8085/SayHello ");
If (obj = null) System. Console. WriteLine ("unable to locate server ");
Else {
Console. WriteLine ("value:" + param. getValue ());
Forwardimethyl after = obj. HelloMethod (param );
Console. WriteLine ("the value after the call is" + after. getValue ());
}
Return 0;
}
}
}

Below isMakefile:

all: server.exe client.exe share.dll

share.dll: share.cs
csc /debug+ /target:library /out:share.dll share.cs

server.exe: server.cs
csc /debug+ /r:share.dll /r:System.Runtime.Remoting.dll server.cs

client.exe: client.cs server.exe
csc /debug+ /r:share.dll /r:server.exe /r:System.Runtime.Remoting.dll client.cs

clean:
@del server.exe client.exe *.pdb *~ *.*~
Appendix B: Example of remote processing using HTTP Channel

Save this fileServer. cs. Here is the server code:

Using System;
Using System. Runtime. Remoting;
Using System. Runtime. Remoting. Channels. HTTP;

Namespace RemotingSamples {
Public class HelloServer: IHello {

Public static int Main (string [] args ){

HTTPChannel chan = new HTTPChannel (8085 );
ChannelServices. RegisterChannel (chan );
RemotingServices. RegisterWellKnownType (
"Server", "RemotingSamples. HelloServer", "SayHello ",
WellKnownObjectMode. SingleCall );
System. Console. WriteLine ("press <enter> to exit ...");
System. Console. ReadLine ();
Return 0;
}

Public HelloServer ()
{
Console. WriteLine ("HelloServer activated ");
}

~ HelloServer ()
{
Console. WriteLine ("Object cleared ");
}

Public forwardimethyl HelloMethod (forwardimethyl obj)
{
Console. WriteLine ("Hello. HelloMethod: {0}", name );
Return "Hi there" + name;
}
}
}

Save this codeClient. cs:

Using System;
Using System. Runtime. Remoting;
Using System. Runtime. Remoting. Channels. HTTP;

Namespace RemotingSamples {
Public class Client
{
Public static int Main (string [] args)
{
HTTPChannel chan = new HTTPChannel ();
ChannelServices. RegisterChannel (chan );
Forwardimethyl param = new forwardimethyl ();
HelloServer obj = (HelloServer) Activator. GetObject (
Typeof (RemotingSamples. HelloServer), "http: // localhost: 8085/SayHello ");
If (obj = null) System. Console. WriteLine ("unable to locate server ");
Else {
Console. WriteLine ("value:" + param. getValue ());
Forwardimethyl after = obj. HelloMethod (param );
Console. WriteLine ("the value after the call is" + after. getValue ());
}
Return 0;
}
}
}

Below isMakefile:

all: server.exe client.exe share.dll

share.dll: share.cs
csc /debug+ /target:library /out:share.dll share.cs

server.exe: server.cs
csc /debug+ /r:share.dll /r:System.Runtime.Remoting.dll server.cs

client.exe: client.cs server.exe
csc /debug+ /r:share.dll /r:server.exe /r:System.Runtime.Remoting.dll client.cs

clean:
@del server.exe client.exe *.pdb *~ *.*~

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.