【IT168 技术文档】.NET Remoting是.NET平台上允许存在于不同应用程序域中的对象相互知晓对方并进行通讯的基础设施。调用对象被称为客户端,而被调用对象则被称为服务器或者服务器对象。简而言之,它就是.NET平台上实现分布式对象系统的框架。
传统的方法调用是通过栈实现,调用方法前将this指针以及方法参数压入线程栈中,线程执行方法时将栈中的参数取出作为本地变量,经过一番计算后,将方法的返回结果压入栈中。这样我们就完成了一次方法调用。如下图所示:
基于栈的方法调用在同一个应用程序域中很容易实现,但是如果要调用的方法所属的对象位于另一个应用程序域或另一个进程甚至是另一个机器,又当如何?应用程序域之间是无法共享同一个线程栈的,此时我们将转而使用另一种方法调用机制——基于消息的方法调用机制。在客户端通过代理对象将原先基于栈的方法调用信息(定位远程对象的信息、方法名、方法参数等)封装到一个消息对象中,再根据需要将这些消息对象转化成某个格式的数据流发送到远程对象所在的的应用程序域中。
当经过格式化的消息到达服务器后,首先从中还原出消息对象,之后在远程对象所在的的应用程序域中构建出相应方法调用栈,此时就可以按照传统的基于栈的方法调用机制完成方法的调用,而方法返回结果的过程则按照之前的方法反向重复一遍。如下图所示:
在基于消息的远程方法调用中主要有以下几个重要角色:
Client Proxy: 负责在客户端处理基于栈的参数传递模式和基于消息的参数传递模式之间的转换。
Invoker:与Client Proxy的功能相反。
Requestor: 负责将消息对象转换成可在网络上传输的数据流,并将其发送到服务器。
Marshaller: 负责消息对象的序列化与反序列化。
Client Request Handle:负责以数据流的格式发送客户端的请求消息。
Server Request Handel:负责接收来自客户端的请求消息。
那么在.NET Remoting框架下,这些重要角色又各自对应了哪些对象呢?下图是一个Remoting框架的示意图:
从中我们可以看到客户端的Transparent Proxy与服务器端的StackBuilderSink分别扮演了Client Proxy与Invoker的角色。Remoting依靠这两个对象实现了基于栈的方法调用与基于消息的方法调用的转换,并且这一过程对于开发者是完全隐藏的。