所谓.NET Remoting就是跨应用程序域边界调用程序集。如图23-16所示,显示了.NET Remoting应用程序的基本构架。
从图23-16中看到,Remoting服务端承载远程对象,使外界能与之通信,对外的信道可以是HTTP、TCP或者IPC。HTTP方式的信道在跨越防火墙上有优势;TCP方式的信道常用在局域网内通信,速度比HTTP快很多;IPC信道用于同一台机器的进程间通信,通信不占用网络资源,速度又比TCP快很多。因此,这里的服务器是一个广义的概念,对于TCP和HTTP信道,服务器可以是两个独立的物理计算机。
那么,最基本的.NET Remoting应用程序应该由三部分构成:
· 服务端。承载远程对象。
· 远程对象。需要跨应用程序域边界调用的程序集。
· 客户端。用于调用远程对象。
远程对象是根本,服务端只是一个载体,那么我们就先来创建一个简单的远程对象:
1.继续使用前面的一个解决方案。右键单击解决方案,选择“添加”→“新建项目”命令,新建一个TestRemoteObject类库项目。
2.把默认的Class1.cs重命名为RemoteObject.cs,打开cs文件,修改代码为:
using System;
namespace RemoteObject
{
public class MyObject : MarshalByRefObject
{
public int Add(int a, int b)
{
return a + b;
}
}
}
在RemoteObject命名空间下有一个MyObject类,除了继承MarshalByRefObject类使之能跨应用程序域边界被访问之外,和一般的类没有任何区别。
3.右键单击这个类库项目,如图23-17所示。

图23-17 项目属性
我们看到这个项目的程序集名为TestRemoteObject,默认的命名空间为TestRemoteObject。默认的命名空间名字和程序集的名字是一样的,但是在代码中我们的命名空间名字为RemoteObject,和程序集名字不同以便进行区分。
注意:程序集和命名空间是两个不同的概念,一个程序集可以包括几个命名空间,一个命名空间也可以由多个程序集来实现。
在创建了远程对象后就需要创建Remoting服务端来发布这个远程对象了。
4.服务端可以是一个控制台应用程序、Windows应用程序、Windows服务甚至是IIS。为了简单,我们将首先使用控制台应用程序做服务端。在解决方案中新建一个名为TestRemotingConsoleServer的控制台应用程序,然后右键单击项目,选择添加应用,如图23-18所示,添加System.Runtime.Remoting的引用。
5.把Program.cs修改成如下:
using System;
using System.Runtime.Remoting;
using System.Runtime.Remoting.Channels;
using System.Runtime.Remoting.Channels.Tcp;
namespace TestRemotingConsoleServer
{
class Program
{
static void Main(string[] args)
{
// 新建一个TCP信道
TcpChannel tc = new TcpChannel(9999);
// 注册TCP信道
ChannelServices.RegisterChannel(tc, false);
// 注册知名对象
RemotingConfiguration.RegisterWellKnownServiceType(typeof(RemoteObject.
MyObject), "myObject", WellKnownObjectMode.SingleCall);
// 让控制台不会自动关闭
Console.ReadLine();
}
}
}

图23-18 添加System.Runtime.Remoting的引用
我们看到,使用.NET Remoting发布远程对象并不复杂,首先需要告知程序使用哪种信道发布远程对象。在这里我们选择TCP信道,并在9999端口通信。然后要告知程序把对象注册为哪种类型,在这里笔者不想详细阐述远程对象的种类和模式,读者只需要理解在这里我们把Remote- Object.MyObject这个类型使用一个固定的名字myObject来发布(因此叫做知名对象),对象的模式是SingleCall,SingleCall模式的对象是无状态的。
最后我们来完成用客户端应用程序调用远程对象。客户端应用程序可以是ASP.NET应用程序、控制台应用程序或者Windows应用程序。那么,我们就直接使用前一节建立的ASP.NET应用程序作为客户端吧。
6.在TestWeb网站下新建一个RemotingTest.aspx,然后在页面的Page_Load事件处理方法中调用远程对象。
protected void Page_Load(object sender, EventArgs e)
{
RemoteObject.MyObject mo = (RemoteObject.MyObject)Activator.GetObject
(typeof(RemoteObject.MyObject), "tcp://localhost:9999/myObject");
Response.Write(mo.Add(1, 2));
}
在这里,我们从远程地址tcp://localhost:9999/myObject创建远程对象,并调用了对象的Add()方法。myObject就是在服务端中为知名对象起的名字。
7.编译整个解决方案,IDE提示“找不到命名空间RemoteObject”,这是因为我们的客户端和服务端项目没有引用远程对象类库项目。右键单击服务端项目,选择“添加引用”,在项目页中找到类库项目,单击“确定”按钮,如图23-19所示。
对于客户端项目也同样添加类库的引用,然后重新编译解决方案。
8.现在就能进行测试了。解决方案中的项目如图23-20所示。

图23-19 添加项目引用 图23-20 解决方案中的项目
要让远程调用成功运行,先要启动服务端使之监听端口。如图23-20所示,单击控制台应用程序,项目名自动以粗体标识,表示这是当前项目,按Ctrl+F5组合键直接启动程序。然后再单击TestWeb网站,右键单击RemotingTest.aspx,选择设为起始页,按Ctrl+F5组合键启动网站。
如图23-21所示,页面显示3,成功了!

图23-21 调用远程对象
注意图23-21所示,在整个过程中需要确保服务端处于运行状态。至此,我们完成了第一个.NET Remoting应用程序。
Kyle
浙公网安备 33010602011771号