基础概念
一、对象类型
1、单次调用对象(Single Call object)
调用一次后被释放,无状态。
2、单一对象(singleton object) 单个实例
多客户端共1个服务端,有状态,COM组件类似
可节省服务器的内存资源等,提高响应速度
3、客户端激活(client-activated object)
客户端调用方法时才激活,这与COM的激活方式一样,随着激活客户端的死亡而消失,如果激活者一直在线又不使用服务端对象,这时造成资源浪费,因此有各种生存期控制方式。
COM组件是综合了(2)(3)二种激活方式。
二、托管程序Managed
用C++编写了.net的执行环境CLR,即C:\WINDOWS\Microsoft.NET\Framework中的各种程序,
用.net编写的程序都在该环境中运行,
该环境提供了托管堆、垃圾回收、JIT编译等服务。
用非.net编写的程序称为非托管程序,它与托管程序之间可以互相调用,但要进行相应的设置。
三、应用程序域AppDomain
不同的应用程序运行在不同程序域中。
但不同应用程序可以共同一个程序域中。
每个正在执行的程序默认有一个程序域。
前面学习远程对象的类型、程序域的概念、跨程序域就是远程调用。方法有:
传送有传值封送MBV(远程对象要Serializable)、
传引用封送MBR(远程对象派生于MarshalByRefObject)
Remoting技术是一种跨域调用技术,它采用MBR调用远程对象,本地创建远程对象代理,方法执行仍在远程域中,其基本组成为:
(1)派生于MarshalByRefObject远程对象,保存在类库文件中。
(2)远程对象的执行环境或宿主程序,可为多种形式。
需要用到Channel、Formatter、StackBuilder.
(3)客户方可为多种形式。
需要用到proxy、 Channel 、Formatter。
1.建立类库文件ClassLib5
usingSystem;
namespaceClassLib5{
publicclass DemoClass:MarshalByRefObject {
//MBR方式发送引用到客户端
private int count = 0;
public DemoClass() {
AppDomain cd = AppDomain.CurrentDomain;
Console.WriteLine(" 远程对象构造时:"+cd.FriendlyName);}
publicvoid ShowCount(){
count++;Console.WriteLine("类中count={0}.", count);}
publicvoid ShowAppDomain(){
AppDomain cd = AppDomain.CurrentDomain;
Console.WriteLine("执行远程对象的域="+cd.FriendlyName);}
public int GetCount() { return count;}}}
2.ClassLib5.dll执行环境ClassLib5Srv.exe(dosapp)
执行“添加引用”选择ClassLib5.dll,还选择如下dll(版本)
C:WINDOWS\Microsoft.NET\Frameworkv\1.4322\System.Runtime.Remoting.dll
using System;//只有此句是向导生成
using ClassLib5;
using System.Runtime.Remoting;
using System.Runtime.Remoting.Channels;
using System.Runtime.Remoting.Channels.Tcp;
using System.Runtime.Remoting.Channels.Http;
namespace ClassLib5Srv{
class Class1{
[STAThread]
static void Main(string[] args) {
IChannelReceiver tcpChn1=new TcpChannel(8601);//tcp
ChannelServices.RegisterChannel(tcpChn1); //注册通道
IChannel httpChn1=new HttpChannel(8602);//http
ChannelServices.RegisterChannel(httpChn1);
RemotingConfiguration.ApplicationName="Remote1";
Type t=typeof(ClassLib5.DemoClass);
//注册服务类,客户方激活方式,可自定义构造函数,有状态
RemotingConfiguration.RegisterActivatedServiceType(t);
Console.WriteLine("远程对象就绪");Console.Read();
}}} //客户方呼叫指定服务器的指定通道
执行“添加引用”选择ClassLib5.dll,尽管选择了此dll,只是用来建立本地代理,还要选择如下dll(注意版本)
C:WINDOWS\Microsoft.NET\Frameworkv\1.4322\System.Runtime.Remoting.dll
using System;
using ClassLib5;
using System.Runtime.Remoting;
using System.Runtime.Remoting.Channels;
using System.Runtime.Remoting.Channels.Tcp;
using System.Runtime.Remoting.Channels.Http;namespaceClassLib5Clt{
classClass1 {
[STAThread]
staticvoid Main(string[] args) {
//IP:端口/程序域,类名
Type t=typeof(ClassLib5.DemoClass); //远程对象类
string url=@"tcp://127.0.0.1:8601/Remote1";
//客户方激活方式,客户端new本地代理时,服务也构造对象
RemotingConfiguration.RegisterActivatedClientType(t,url);
ClassLib5.DemoClassobj=new DemoClass();//本地代理
Console.WriteLine("本地代理已创建");Console.Read();
obj.ShowAppDomain(); //执行结果显示在服务器中
obj.ShowCount();
Console.WriteLine("远程返回的count="+
obj.GetCount().ToString());Console.ReadLine();}}}
通过ClassLib5Srv.exe与ClassLib5Clt.exe的执行可知,
当客户方建立远程对象的本地代理时,远程对象的构造函数被调用即远程对象被创建,与COM稍有不同,执行远程方法时才创建远程对象。
每创建本地代理,就创建一个远程对象,非单实例!
这种方式,称为客户方激话。
服务方注册对象方法:
Type t=typeof(ClassLib5.DemoClass);//远程对象类RemotingConfiguration.RegisterActivatedServiceType(t);
客户方调用对象的方法:
Type t=typeof(ClassLib5.DemoClass);//远程对象类
stringurl=@"tcp://127.0.0.1:8601/Remote1";//位置 RemotingConfiguration.RegisterActivatedClientType(t,url);