.NET Remoting

.NET远程处理(.NET Remoting)是微软.NETFramework中的一种网络通讯技术,与 XML Web Service 不同的是,它可以使用SOAP以外的协议来通讯,而在服务端和客户端之间所操作的方法近乎相同,客户端可以不必考虑使用的协议,即可访问服务端所开放的对象。这个技术与是由DistributedCOM所发展而来的,与DCOM最大的不同是,DCOM有限制使用TCP Port,但.NETRemoting可以选择使用TCPHTTP的方式通讯,而数据可以利用SOAP或二进制传输方式在网络上流动,二进制的传输性能是SOAP所不能比的,但SOAP却可以得到和Web Service相互沟通的能力,因此 .NET Remoting的设计弹性较大。

.NET Remoting 技术目前已集成到Windows Communication Foundation中。

原理

.NET Remoting 使用了信道序列化机制来串接两台机器间的对象,信道是负责处理网络通讯的部分,而序列化则是处理对象与流数据的处理工作。

·        信道支持了 IPC(进程间通讯)、TCPHTTP通讯协议

·        序列化支持二进制(binary)或 XMLSOAP)通讯协议的数据流。

当服务端设置好使用的通道以及协议后,客户端必须要跟随服务端的设置,并且依服务端决定的活化模型来启动。

配置设

.NET Remoting 的设计理念,就是为了要简化网络上的对象通讯,而且要让开发人员不必太过于在通讯的底层伤脑筋,因此在网络通讯协议上做了许多的包装,并且允许在Configuration Fileapp.config)中直接设置,或是由 .NET Remoting Configuration API来设置即可,设计较复杂的 .NET Remoting应用程序在配置的设置上往往会相当复杂

活化模

活化(Activation)是指客户端启动服务端组件的方式,.NET Remoting中支持了两种方式:

·        Single-Call:在每一次客户端调用时都生成一个运行个体。

·        Single-ton:在第一次调用时就生成运行个体,之后每一次调用都使用相同的运行个体。

.NET remoting provides a number of activation models to choose from. These models fall into two categories:

·        Client-activated objects

·        Server-activated objects

Client-activated objects are under the control of a lease-based lifetime manager that ensures that the object is garbage collected when its lease expires. In the case of server-activated objects, developers have a choice of selecting either a "single call" or "singleton" model. The lifetime of singletons are also controlled by lease-based lifetime.

from MSDN

对象传

.NET Remoting中,不论是传值或传址,每一个对象都必须要继承System.MarshalByRefObject类,才可以利用.NET Remoting 来传输

Remote Objects

One of the main objectives of any remoting framework is to provide the necessary infrastructure that hides the complexities of calling methods on remote objects and returning results. Any object outside the application domain of the caller should be considered remote, even if theobjects are executing on the same machine. Inside the application domain, all objects are passed by reference while primitive data types are passed by value.Since local object references are only valid inside the application domain where they are created, they cannot be passed to or returned from remote methodcalls in that form. All local objects that have to cross the application domain boundary have to be passed by value and should be marked with the[serializable] custom attribute, or they have to implement the ISerializable interface. When the object is passed as a parameter, the framework serializesthe object and transports it to the destination application domain, where the object will be reconstructed. Local objects that cannot be serialized cannot be passed to a different application domain and are therefore nonremotable.

Any object can be changed into a remote object by deriving it fromMarshalByRefObject. When a client activates a remote object, it receives a proxy to the remote object. All operations on this proxy are appropriately indirected to enable the remoting infrastructure to intercept and forward the calls appropriately. This indirection does have some impact on performance, but the JIT compiler and execution engine (EE) have been optimized to prevent unnecessary performance penalties when the proxy and remote object reside in the same application domain. In cases where the proxy and remote objects are in different application domains, all method call parameters on the stack are converted into messages and transported to the remote application domain, where the messages are turned back into a stack frame and the method call is invoked. The same procedure is used for returning results from the method call.

Proxy Objects

Proxy objects are created when a client activates a remote object. The proxy objectacts as a representative of the remote object and ensures that all calls made on the proxy are forwarded to the correct remote object instance.

When a client activates a remote object, the framework creates a local instance of the classTransparentProxy that contains a list of all classes, as well as interface methods of the remote object. Since theTransparentProxy class is registered with the CLR when it gets created, all method calls on the proxy are intercepted by the runtime. Here the call is examined to determine if it is a valid method of the remote object and if an instance of the remote object resides in the same application domain as the proxy. If this is true, a simple method call is routed to the actual object. If the object is in a different application domain, the call parameters on the stack are packaged into anIMessage object and forwarded to a RealProxy class by calling itsInvoke method. This class is responsible for forwarding messages to the remote object. Both theTransparentProxy and RealProxy classes are created under the covers when a remote objectis activated, but only theTransparentProxy is returned to the client.

In order to gain a better understanding of these proxy objects, we need to take a detour and briefly mentionObjRef. The following scenario describes briefly how ObjRefand the two proxy classes are related. (It is important to note that this is a very broad description of the process; some variations exist, depending on whether objects are client or server activated, and if they are singleton or single-callobjects.)

·        A remote object is registered in an application domain on a remote machine. The object is marshaled to produce anObjRef. The ObjRef contains all the information required to locate and access the remote objectfrom anywhere on the network. This information includes the strong name of theclass, the class's hierarchy (its parents), the names of all the interfaces the class implements, the object URI, and details of all available channels that have been registered. The remoting framework uses the object URI to retrieve theObjRef instance created for the remote object when it receives arequest for that object.

·        A client activates a remote object by callingnew or one of the Activator functions like CreateInstance. In the case of server-activated objects, the TransparentProxy for the remote object is produced in the client application domain and returned to the client, no remote calls are made at all. The remote object is only activated when the client calls a method on the remote object.

(This scenario will obviously not work for client-activated objects, since the client expects the framework to activate the object when asked to do so.) When a client calls one of the activation methods, an activation proxy is created on the client and aremote call is initiated to a remote activator on the server using the URL and object URI as the endpoint. The remote activator activates the object, and anObjRef is streamed to the client, where it is unmarshaled to produce aTransparentProxy that is returned to the client.)

·        During unmarshaling, theObjRef is parsed to extract the method information of the remote object and both theTransparentProxy and RealProxy objects are created. The content of the parsedObjRef is added to the internal tables of the TransparentProxy before the latter is registered with the CLR.

·        WhenInvoke is called, a class derived from RealProxy can obtain load information about servers on the network and route the call to an appropriate server. Simply request aMessageSink for the required ObjectURI from the Channel and callSyncProcessMessage or AsyncProcessMessage to forward the call to the required remote object. When the call returns, theRealProxy automatically handles the return parameter.

Channels

Channels are used to transport messages to and from remote objects.

  • HTTP Channel

The HTTP channel transports messages to and from remote objects using the SOAP protocol. All messages are passed through the SOAP formatter, where the message is changed into XML and serialized, and the required SOAP headers are added to the stream. It is also possible to configure the HTTP Channel to use the binary formatter. The resulting data stream is then transported to the target URI using the HTTP protocol.

  • TCP Channel

The TCP channel uses a binary formatter to serialize all messages to a binary stream and transport the streamto the target URI using the TCP protocol. It is also possible to configure theTCP channel to the SOAP formatter.

 

All remote objects have to be registered with the remoting framework before clients can access them. Object registration is normally done by a hosting application that starts up, registers one or more channels with ChannelServices, registers one or more remote objects withRemotingConfiguration, and then waits until it is terminated. It is important to note that the registered channels and objects are only available while the process that registered them is alive. When the process quits, all channels and objects registered by this process are automatically removed from the remoting services where they were registered. The following four pieces of information are required when registering a remote object with the framework:

The following four pieces of information are required when registering a remote object with the framework:

1.     The assembly name in which the class is contained.

2.     The Type name of the remote object.

3.     The object URI that clients will use to locate the object. //The ObjectURI can be any text string for direct hosting

4.     The object mode required for server activation. This can beSingleCall or Singleton.

A remote object can be registered by calling RegisterWellKnownServiceType, passing the information above as parameters, or by storing the above information in a configuration file and then callingConfigure, thus passing the name of the configuration file as a parameter. Either of these two functions can be used to register remote objects as they perform exactly the same function. The latter is more convenient to use since the contents of the configuration file can be altered without recompiling the host application.

When the object is registered, the framework creates an object reference for this remote object and then extracts the required metadata about the object from the assembly. This information, together with the URI and assembly name, is then stored in the object reference that is filed in a remoting framework table used for tracking registered remote objects. It is important to note that the remote object itself is not instantiated by the registration process.

Any client that knows the URI of this object can now obtain a proxy for this object by registering the channel it prefers withChannelServices and activating the object by calling new,GetObject, or CreateInstance.

GetObject ornew can be used for server activation. It is important to note that the remote object is not instantiated when either of these calls is made. As a matter of fact, no network calls are generated at all. The framework obtains enough information from the metadata to create the proxy without connecting to the remote object at all. A network connection is only established when the client calls a method on the proxy. When the call arrives at the server, the framework extracts the URI from the message, examines the remoting framework tables to locate the reference for the object that matches the URI, and then instantiates the object if necessary, forwarding the method call to the object. If the object is registered asSingleCall, it is destroyed after the method call is completed. A new instance of the object is created for each method called. The only difference betweenGetObject and new is that the former allows you to specify a URL as a parameter, where the latter obtains the URL from the configuration.


在.Net Remoting中,采用远程代理模式。代理在.Net中被分为透明代理(Transparent Proxy)和真实代理(Real Proxy)。
Transparent Proxy的目标是在CLR中在IL层面最大程度扮演被代理的远端对象,从类型转换到类型获取,从字段访问到方法调用。对CLR的使用者来说,Transparent Proxy和被其代理的对象完全没有任何区别,只是通过RemotingServices.IsTransparentProxy才能区分两者的区别。
Real Proxy则是提供给CLR使用者扩展代理机制的切入点,通过从Real Proxy继承并实现Invoke方法,用户自定义代理可以自由的处理已经被从栈调用转换为消息调用的目标对象方法调用,如实现缓存、身份验证、安全检测、延迟加载等等。
当客户端发起一个远程调用后,透明代理为该远程调用生成一个IMessage对象,并将它传给实际代理。之后,实际代理会查询特定远程对象相关的配置信息,再决定加载哪些消息接收器来处理该远程调用。代理把Imessage对象传给消息接收器来处理该远程调用。
实际代理至少需要加载两个消息接收器:
1.格式转换接收器(binary和soap),负责将IMessage对象序列化为数据流,最终再由网络传送出去。
2.传送接收器(http和tcp),负责把数据流输送到目的地或远程服务器。

Caller --> [Transparent Proxy] --IMessage--> [Real Proxy] --IMessage2--> [消息接收器】 ---->传送到远端

http://www.360doc.com/content/11/1013/11/6075898_155689130.shtml


Remoting Sample Using a TCP Channel:

Project “ClassLibrary” contains class HelloService

Project “RemotingSamples” and “Client” depends on “ClassLibrary”

以下是程序代码:

 ------------ClassLibrary:  program.cs--------------

using System;

namespace RemotingSamples
{
    public class HelloService : MarshalByRefObject
    {
        public HelloService()
        {
            Console.WriteLine("HelloService activated");
        }

        public String HelloMethod(String name)
        {
            Console.WriteLine("Hello.HelloMethod: {0}", name);
            return "Hi there " + name;
        }
    }
}

-----------RemotingSamples:server.cs---------------
using System;
using System.Runtime.Remoting;
using System.Runtime.Remoting.Channels;
using System.Runtime.Remoting.Channels.Tcp;

namespace RemotingSamples
{
    class Sample
    {
        static void Main(string[] args)
        {
            TcpChannel chan = new TcpChannel(8085);
            ChannelServices.RegisterChannel(chan,true);
            //RemotingSamples is the namespace;
            //HelloService is the name of the class;
            //ClassLibrary.dll is the name of the assembly.
            RemotingConfiguration.RegisterWellKnownServiceType
                (Type.GetType("RemotingSamples.HelloService,ClassLibrary"),
                "SayHello", WellKnownObjectMode.Singleton);

            System.Console.WriteLine("Hit <enter> to exit...");
            System.Console.ReadLine();
            return;
        }
    }
}

-----------Client: client.cs---------------
using System;
using System.Runtime.Remoting.Channels;
using System.Runtime.Remoting.Channels.Tcp;

namespace RemotingSamples
{
    class client
    {
        static void Main(string[] args)
        {
            TcpChannel chan = new TcpChannel();
            ChannelServices.RegisterChannel(chan, true);
            HelloService obj = (HelloService)Activator.GetObject(typeof(RemotingSamples.HelloService), "tcp://localhost:8085/SayHello");

            if (obj == null)
                System.Console.WriteLine("Could not locate server");
            else
                System.Console.WriteLine(obj.HelloMethod("Caveman"));

            System.Console.WriteLine("Hit <enter> to exit...");
            System.Console.ReadLine();

            return;
        }
    }
}

启动Server,然后运行Client请求服务

Hit <enter> to exit...
HelloService activated
Hello.HelloMethod: Caveman
Hello.HelloMethod: Caveman
HelloService activated
Hello.HelloMethod: Caveman


   

Refer to: Microsoft .NET Remoting: A Technical Overview

(https://msdn.microsoft.com/zh-cn/subscriptions/ms973857.aspx)

https://msdn.microsoft.com/zh-cn/subscriptions/downloads/xws7132e(v=vs.71).aspx


 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值