1.Remoting的词根——Remote
Remote Object
分布式对象
2.Remoting的优势
性能
扩展性
可配置性
安全
生存周期管理
Remoting使用的技术
1.XML
2.SOAP
简单对象传输协议
3.序列化
添加SerializableAttribute
实现ISerializable 接口
远程对象的两个含义
1.操作远程对象
对象运行在远程,客户端向他发送消息,他来自行。
MarshalByRefObject (所传递的远程对象类必须继承自MarshalByRefObject,以引用方式传递.)
2.传递远程对象
将远程的对象拿到本地,或者将本地对象发送过去。
对副本进行操作
[Serializable] 或ISerializable
谁来激活对象
1.服务器激活(WellKnown)
Singleton
SingleCall
2.客户端激活
通道(Channels)
1.一个远程对象使用通道发送和接收消息
服务器选择一个通道来监听请求(request)
客户端选择通道来和服务器通讯
2.Remoting提供了内置的通道
TCP通道和HTTP通道
你也可以编写自己的通道
开发Remoting三步走
第一步:创建远程对象
必须继承自System.MarshalByRefObject
public class HelloServer : MarshalByRefObject
{
……
}
using System.Collections.Generic;
using System.Text;
namespace RemotingSamples
{
public class HelloServer : MarshalByRefObject
{
public HelloServer()
{
Console.WriteLine("HelloServer activated");
}
public String HelloMethod(String name)
{
Console.WriteLine(
"Server Hello.HelloMethod : {0}", name);
return "Hi there " + name;
}
}
}
第二步:创建宿主应用程序
创建一个应用程序作为“宿主(host)”,以接收客户请求,可以是控制台程序,也可以是windows程序.常用方法是作成windows服务,或者发布到iis,将远程对象暴露为web service
1.注册通道
内置通道:TCP,HTTP
2.注册服务器激活的远程对象(WellKnown)
Singleton,SingleCall
URL
3.运行宿主程序
using System.Runtime.Remoting;
using System.Runtime.Remoting.Channels;
using System.Runtime.Remoting.Channels.Tcp;
using System.Runtime.Remoting.Channels.Http;
namespace RemotingSamples
{
public class Server
{
public static int Main(string [] args)
{
TcpChannel chan1 = new TcpChannel(8085);//tcp通道,监听端口号8085
HttpChannel chan2 = new HttpChannel(8086);//http通道,监听端口号8086
ChannelServices.RegisterChannel(chan1);
ChannelServices.RegisterChannel(chan2);
RemotingConfiguration.RegisterWellKnownServiceType
(
typeof(HelloServer),
"SayHello",
WellKnownObjectMode.Singleton
);
System.Console.WriteLine("Press Enter key to exit");
System.Console.ReadLine();
return 0;
}
}
}
第三步:建立客户端程序
1.注册通道(与服务器端一样)
内置通道:TCP,HTTP
2.根据URL得到对象代理
3.使用代理调用远程对象
using System.Runtime.Remoting;
using System.Runtime.Remoting.Channels;
using System.Runtime.Remoting.Channels.Tcp;
using System.Runtime.Remoting.Channels.Http;
using System.IO;
namespace RemotingSamples
{
public class Client
{
public static void Main(string[] args)
{
//使用TCP通道得到远程对象
TcpChannel chan1 = new TcpChannel();//不需要监听端口号
ChannelServices.RegisterChannel(chan1);
HelloServer obj1 = (HelloServer)Activator.GetObject(
typeof(RemotingSamples.HelloServer),
"tcp://localhost:8085/SayHello");
if (obj1 == null)
{
System.Console.WriteLine(
"Could not locate TCP server");
}
//使用HTTP通道得到远程对象
HttpChannel chan2 = new HttpChannel();
ChannelServices.RegisterChannel(chan2);
HelloServer obj2 = (HelloServer)Activator.GetObject(
typeof(RemotingSamples.HelloServer),
"http://localhost:8086/SayHello");
if (obj2 == null)
{
System.Console.WriteLine(
"Could not locate HTTP server");
}
Console.WriteLine(
"Client1 TCP HelloMethod {0}",
obj1.HelloMethod("Caveman1"));
Console.WriteLine(
"Client2 HTTP HelloMethod {0}",
obj2.HelloMethod("Caveman2"));
Console.ReadLine();
}
/*
RemotingConfiguration.Configure(@"C:\Documents and Settings\RenMin\桌面\Remoting\Demo\02-SimpleRemoting\Client\client.exe.config");
HelloServer obj2 = new HelloServer();
*/
}
}
传递参数(必须是可序列化的对象)
1.传递简单类型
int,doulbe,string,enum……
2.传递可序列化的类型
ArrayList,Hashtable,DataSet……
3.传递自定义类型
[Serializable]
Singleton VS. SingleCall
1.都是服务器激活的对象(WellKnown)
2.Singleton(单实例)
在服务器端只实例化一次。
以后每次调用都访问同一个实例。不论同一客户端还是不同客户端。
可以维持状态。
3.SingleCalll(单调用)
每次调用都实例化新的实例。
更好的支持无状态编程模型
Serialization VS. MarshalByRefObject
远程对象中的成员或参数
1.按值列集(Serialization)
得到远程对象的副本。
对副本的操作不影响远程对象。
不论远程对象是Singleton还是SingleCall
2.按引用列集( MarshalByRefObject )
1.得到远程对象引用,本地创建代理(Proxy)
2.通过(Proxy)对远程对象访问。
3.Singleton记录更改,SingleCall无状态。
Remoting的模式
1.服务器/客户端模式
2.如果实现端对端(Peer-to-Peer)
则每个段既是服务器又是客户端