技术开发 频道

Remoting基本原理及其扩展机制(下)

    MessageSink Region

    不知你是否记得之前提到的四个接口:IContributeEnvoySink、IContributeServerContextSink、IContributeObjectSink、IContributeClientContextSink。其实它们分别代表了四个不同的消息接收器区域:服务器(server)区域、对象(object)区域、信使(envoy)区域和客户端(client)区域。要理解区域概念,你必须考虑上下文绑定的对象是否被位于另一个上下文的实体调用。这个实体可以是一个静态方法或者另一个对象。在我们关于区域的讨论中,我们把这个实体所在的上下文称为调用方上下文(calling context),而把被调用对象所在的上下文称为目标上下文(target context)。目标上下文中的每个属性都可以在这些区域中注入消息接收器。

    1.注入服务器区域的消息接收器拦截所有从另一个上下文发往目标上下文中所有对象的调用消息。于是,每个目标上下文有一个服务器区域。
    2.注入对象区域的消息接收器拦截所有从另一个上下文发往目标对象中特定对象的调用消息。于是,上下文中每个对象会有一个对象区域。
    3.注入信使区域的消息接收器拦截所有从另一个上下文发往目标对象中特定对象的调用消息。信使区域和对象区域的不同点是信使区域位于调用方上下文而不是包含对象的目标上下文。我们使用信使区域把调用方上下文的信息传递给目标上下文的消息接收器。
    4.注入客户端区域的消息接收器拦截所有从目标上下文发往位于其他上下文的对象的调用消息。于是,每个目标上下文有一个客户端区域。你可能会对这个区域所处的位置有点困惑,似乎当它位于Calling context的信使区域下方时会显得更加对称。之所以会有这样的误解,是因为我们对Server、Client的理解有了偏差。你应该记住除了信使区域是位于Calling context外,另外三个区域都是处在Target Context。而所谓的Server,Client是针对处在Target Context中的对象在某不同时刻所扮演不同角色而言的。当然Calling context中也会有客户端区域,不过其中的MessageSink不是通过Target context的属性注入的,而应该依靠Calling context中的上下文属性注入。

 

    上图说明了区域的概念。目标上下文包含名为OBJ1和OBJ2的两个对象。我们选择在目标上下文中放置两个对象而不是一个是为了更好地说明对象区域和信使区域是在对象层面与消息的拦截关联起来的,而服务器区域和客户端区域则是在上下文层面与消息的拦截关联起来的。
    我们在每个区域中放置了两个自定义消息接收器是为了更好地说明一个区域能包含零个、一个或多个消息接收器。具体地说,所有自定义消息接收器都通过目标上下文的属性注入区域,即使这个区域不属于目标上下文。因为你可以定义你自己的上下文属性类,你可以选择必须注入哪个消息接收器。

    你可能注意到每个区域都包含一个用于通知CLR退出区域的系统终结器接收器(system terminator sink),它是由Remoting框架定义的,并且总是位于每个区域的末尾。

    当调用方上下文和目标上下文处在同一个应用程序域中时,CLR会使用mscorlib.dll中CrossContextChannel内部类的实例作为信道。这个实例会使得当前线程的Context属性发生切换。图中也展示了这一实例。

0
相关文章