remoting草稿

六:远程对象的传送方式

    可远程处理的对象是能在大范围的分布环境中正常运行的对象。可远程处理的对象既可以使用代理在其应用程序域或上下文外部访问,也可以复制它们并且可以将这些副本传递到它们的应用程序域或上下文外;换句话说,某些可远程处理的对象通过引用传递,而另一些通过值传递。有两种主要的可远程处理的对象:

  • 按值封送对象,它们被复制并传出应用程序域。
    远程类用
    [Serializable]进行标识。在抽象级别上,这种方案类似于客户端浏览器所请求的静态 HTML 页的方案。服务器复制文件,将其写入到流中,发送出去,然后忘掉它。所有后续的请求都只是对其他副本的其他请求。使用代码实验,客户端创建远程对象类Person p = new Person()后,改变P.Name。在服务器得到这个类的原始对象,发现P的值在服务器没有改变。
  • 按引用封送对象,将为其创建代理,而该代理由客户端用于远程访问对象。
    远程类
    实现MarshalByRefObject。这个时候发现在客户端修改P.Name,在服务器上,该值也发生了改变。同时,如果在服务器上对该值进行了改变,你也会发现客户端的值做出了相应的变动。
    根据资料显示,如果网速过慢,使用这类方式,就会带来效率上的问题。


七:对象激活和生存期
    对象的生存期,类似于WEB应用中的SESSION,远程对象的默认生存期是10分钟。像上文代码中,如果客户端和服务器端10分钟不操作远程对象,则远程对象将会在10分钟后被释放掉,这个时候,在客户端和服务器端再次访问远程对象,远程对象就会被重新被创建。

  • 多数情况下,无需注意创建对象的确切时间;只需在对象上调用方法时让它作出响应。然而,当生成远程对象时,必须知道新对象是何时以及如何创建和初始化的,即它是如何激活的。在可以使对象对于客户端可用之前,远程处理系统必须总是知道需要哪种类型的激活;因此,理解您的选择是很重要的。

    激活

    对于按引用封送 (MBR) 的对象,有两种激活类型:服务器激活和客户端激活。

    服务器激活的对象:

  • 只在需要它们时由服务器创建——不是在通过调用 new 或 Activator.GetObject() 创建客户端代理时创建,而是在客户端调用该代理上的第一个方法时创建。
  • 可以声明为 SingletonSingleCall 对象。Singleton 对象是这样的对象:无论该对象有多少个客户端,总是只有一个实例,且该对象具有默认的生存期。将对象声明为 SingleCall 对象时,系统为每个客户端方法调用创建一个新对象。客户端可以使用生存期租约系统参与这些实例的生存期。

客户端激活的对象:

  • 客户端调用 new 或 Activator.CreateInstance() 时在服务器上创建。使用生存期租约系统,客户端本身可以参与这些实例的生存期。


生存期租约

    按引用封送的对象 (MBR)无论是服务器激活的 Singleton 对象还是客户端激活的对象,都不会永远驻留在内存中。相反,除非该类型重写 MarshalByRefObject.InitializeLifetimeService() 以控制自己的生存期策略,否则每个 MBR 的生存期都是由租约、租约管理器和一些主办方的组合控制的。(在这种情况下,MBR 对象的生存期是对象在内存中保持活动状态的总时间。)租约本身是 .NET 远程处理系统开始删除某个特定对象并回收内存的进程之前,该特定对象在内存中保持活动状态的时间。服务器应用程序域的租约管理器是确定何时标记远程对象以供进行垃圾回收的对象。主办方是可以通过将其本身注册到租约管理器来为特定对象请求新租约的对象。

只要 MBR 对象被在应用程序域外部进行远程处理,就为该对象创建生存期租约。每个应用程序域都包含一个负责管理其域中的租约的租约管理器。租约管理器定期检查所有租约以确定过期的租约时间。如果租约已过期,租约管理器将为该对象遍历它的主办方列表并请求它们中是否有谁要续订租约。如果没有任何主办方续订该租约,租约管理器将移除该租约,该对象被删除,其内存被垃圾回收机制回收。因此,如果对象被主办方多次续订租约或被客户端持续调用,其生存期可以比其生存期租约长得多。

    由于远程对象的生存独立于其客户端的生存,因此简单或轻量对象的租约(举个例子来说)可以很长并被一些客户端使用,前提是该租约被管理器或客户端定期续订。这种方法高效地使用租约,原因是分布式垃圾回收所需的网络通信量很小。另一方面,对于使用时间不太长和使用稀有资源的远程对象来说,其租约的生存期可以很短,以至于客户端用较短的时间频繁地续订其生存期。当所有客户端都完成对远程对象的处理时,.NET 远程处理系统将很快删除该对象。这种策略增加了网络通信量以更有效地使用服务器资源。

使用租约管理远程对象的生存期是引用计数的一种替换方法,引用计数在不可靠的网络连接上可能是复杂而低效的。虽然可以将租约配置为延长远程对象的生存期以超过所需的精确长度,但是由于减少了专用于引用计数和进行 ping 操作的客户端的网络通信量,因而使租约在为特定方案正确配置时成为一种很有吸引力的解决方案。

租约有五个主要属性:

  • InitialLeaseTime。它指定对象在租约管理器开始删除对象的过程之前将保留在内存中的初始时间长度。在配置文件中,它是 <lifetime> 配置元素的 leaseTime 属性。默认为 5 分钟。租约时间为零则将租约设置为具有无限长的生存期。
  • CurrentLeaseTime。它指定在租约过期之前所剩下的时间长度。当租约被续订时,其 CurrentLeaseTime 被设置为 CurrentLeaseTime 的最大值或 RenewOnCallTime
  • RenewOnCallTime。它指定对对象进行各个远程调用后将 CurrentLeaseTime 设置为的最大时间长度。默认为 2 分钟。
  • SponsorshipTimeout。它指定租约管理器被通知租约已过期时租约管理器等待主办方响应的时间。如果主办方未在指定的时间内响应,则移除该主办方并调用另一主办方。如果没有其他主办方,则租约过期,且垃圾回收器将处置该远程对象。如果值为“0”(TimeSpan.Zero),则租约将不注册主办方。默认为 2 分钟。
  • LeaseManagerPollTime。它是租约管理器在检查过期的租约之后休眠的时间量。默认的 LeaseManagerPollTime 为 10 秒钟。

    当 MBR 对象在其他应用程序域中被激活时创建租约。此时,当 ILease.CurrentState 属性为 LeaseState.Initial 时,可以设置租约的属性。一旦设置,就不能直接更改它们。只可以从 ILease.Renew 调用中或者当租约管理器在主办方上调用 ISponsor.Renewal 且该主办方用一个 TimeSpan 响应时更改 CurrentLeaseTimeMarshalByRefObject 具有生存期租约的默认实现,且除非该租约在创建时被修改,否则租约属性将始终相同。

修改租约属性

可以通过两种方式修改生存期租约属性。可以声明自定义生存期租约属性,方法是重写 MBR 对象中的 MarshalByRefObject.InitializeLifetimeService 以自己设置租约的属性,或者将其重写为返回 null(Visual Basic 中为 Nothing);后一种方法通知 .NET 远程处理系统该类型的实例将具有无限长的生存期。您或者管理员还可以在特定的应用程序或计算机配置文件中的 <lifetime> 元素内指定该应用程序中所有对象的生存期属性。

创建后,可以用三种方式续订租约:

  • 客户端直接调用 ILease.Renew 方法。
  • 如果设置了 ILease.RenewOnCallTime 属性,则每个对远程对象的调用都将为租约续订指定的时间。
  • 租约调用 ISponsor.Renewal 方法以请求续订租约,而主办方则以一个 TimeSpan 响应。

    1. 通过编程的方式:通过设置System.Runtime.Remoting.Lifetime. LifetimeServices静态属性。

    LifetimeServices.LeaseManagerPollTime = TimeSpan.FromMinutes(2);
    LifetimeServices.LeaseTime 
    = TimeSpan.FromMinutes(2);
    LifetimeServices.RenewOnCallTime 
    = TimeSpan.FromMinutes(2);
    LifetimeServices.SponsorshipTimeout 
    = TimeSpan.FromMinutes(2);

    2. 通过Configuration的方式

    <lifetime  leaseTime="7M"  sponsorshipTimeout="7M"  renewOnCallTime="7M" 
    leaseManagerPollTime
    ="7S" />

    3. 定制单个MarshalByRefObject 对象的Lease 时间:Override 继承自MarshalByRefObject 的InitializeLifetimeService方法。

    public override object InitializeLifetimeService()
            
    {
                ILease lease 
    = (ILease)base.InitializeLifetimeService();
                
    if (lease.CurrentState == LeaseState.Initial)
                
    {
                    lease.InitialLeaseTime 
    = TimeSpan.FromSeconds(1);
                    lease.RenewOnCallTime 
    = TimeSpan.FromSeconds(1);
                    lease.SponsorshipTimeout 
    = TimeSpan.FromSeconds(1);
                }

                
    return lease;           
            }

租约管理器

    租约管理器的任务之一是定期检查租约的时间是否过期。当租约的时间已过期时,该租约将接到通知并尝试通过调用其主办方来续订自己。

    租约管理器还维护一个租约正等待其答复的主办方的列表。如果主办方未在 SponsorshipTimeOut 时间长度所指定的间隔内响应,则将其从主办方列表中移除。

    租约被允许过期时,它不再接受任何其他租约消息或主办方返回的内容。租约的引用被从租约列表中移除,而且 .NET 远程处理系统将把该对象引用从其内部表中移除。然后,垃圾回收系统将移除该租约和对象。

信道

    信道是跨远程处理边界(无论是在应用程序域、进程还是计算机之间)在应用程序之间传输消息的对象。信道可以在终结点上侦听入站消息,向另一个终结点发送出站消息,或者两者都可以。这使您能够插入各种各样的协议,即使信道的另一端上没有公共语言运行库。

    信道必须实现 IChannel 接口,该接口提供诸如 ChannelName ChannelPriority 这样的信息性属性。被设计为在特定端口上侦听特定协议的信道实现 IChannelReceiver,而被设计为发送信息的信道IChannelSender。TcpChannelHttpChannel 对于这两种接口都加以实现,因此它们可用于发送或接收信息。

    您可以以两种方式将信道注册到远程处理基础结构:

  • 如果您正在发布可远程处理的对象,则在注册服务器对象之前调用 ChannelServices.RegisterChannel()。
  • 如果您正在使用可远程处理的对象的功能,则在创建服务器对象的实例之前调用 ChannelServices.RegisterChannel()

    信道还可以从远程处理配置文件加载。

    在客户端,消息经过客户端上下文链后,被传递到客户端信道接收链。第一个信道接收器通常是格式化程序接收器;它将消息序列化为流(然后该流将被沿着信道接收链传递到客户端传输接收器)。然后客户端传输接收器将此流写出到网络。

    在服务器端,服务器传输接收器从网络读取请求,并将该请求流传递到服务器信道接收链。此链末端的服务器格式化程序接收器将该请求反序列化为消息。然后将此消息传递到远程处理基础结构。


八:一个较为详细的例子
    在设计之初,考虑到远程对象为一个RoomServer,然后一个RoomServer可以生成多个ClientPc,所有的ClientPc保存在一个ArrayList TotalClients中。
    这样一来,就带来安全上的隐患,也就是说所有的客户端都可以得到RoomServer这个对象。于是,我们采用另外一种设计思路,采用客户端激活的模式,这样,所有的客户端就只能得到自己的对象,且,保存了生存周期。


五:安全
.net remoting http://msdn.microsoft.com/en-us/library/ms973911.aspx

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值