.NET Remoting是一种分布式技术,当客户端调用远程服务端对象的时候,取得一个Proxy对象,对此对象的操作将被Formatter转换成SOAP或Binary消息,然后通过通信协议Http或者Tcp传到远程服务端。服务端将调用Dispatcher组件,将消息分发到不同的Message Sink对调用做出反应。
.NET Remoting对象的创建方式有两种,SAO(Server Activate Object)服务端激活 和CAO(Client Activate Object)客户端激活,其中SAO可以通过RegisterConfiguration.RegisterWellKnownType将对象创建为WellKnownObjectMode.Singleton模式或WellKnownObjectMode.SingleCall模式。
其中前者将会对所有的调用请求启用同一个服务对象,而后者将对不同的请求启用不同的服务对象。SAO调用示例可以通过共享一个数据契约程序集(契约的实现不必提供给客户端)供Client和Server端调用。
Ø SAO调用示例
服务契约
using System.Collections.Generic;
using System.Text;
namespace ShareDLL
{
public interface IMyService
{
string SayHello(string name);
}
[Serializable]
public class PersonData
{
private string _name;
public string Name
{
get { return _name; }
set { _name = value; }
}
private int _age;
public int Age
{
get { return _age; }
set { _age = value; }
}
public PersonData(string name, int age)
{
this._name = name;
this._age = age;
}
}
}
服务端
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.Remoting;
using System.Runtime.Remoting.Channels;
using System.Runtime.Remoting.Channels.Tcp;
namespace Server
{
class Program
{
static void Main(string[] args)
{
TcpChannel chnl = new TcpChannel(9012);
ChannelServices.RegisterChannel(chnl, false);
//SingleCall方式
RemotingConfiguration.RegisterWellKnownServiceType(typeof(MyServiceImpl),
"myservice.rem",
WellKnownObjectMode.SingleCall);
//Singleton方式
//RemotingConfiguration.RegisterWellKnownServiceType(typeof(MyServiceImpl),
// "myservice.rem",
// WellKnownObjectMode.Singleton);
Console.WriteLine("Server is Running...");
Console.Read();
}
}
public class MyServiceImpl : MarshalByRefObject,ShareDLL.IMyService
{
public string SayHello(string name)
{
return string.Format(@" Message from Server :"+ name);
}
}
}
客户端
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.Remoting;
using System.Runtime.Remoting.Channels;
using System.Runtime.Remoting.Channels.Tcp;
namespace Client
{
class Program
{
static void Main(string[] args)
{
TcpChannel chnl = new TcpChannel();
ChannelServices.RegisterChannel(chnl, false);
ShareDLL.IMyService service=(ShareDLL.IMyService)Activator.GetObject(typeof(ShareDLL.IMyService),
"tcp://localhost:9012/myservice.rem");
Console.WriteLine(service.SayHello("code6421"));
Console.Read();
}
}
}
关于CAO创建对象,用三种方式,
Ø Share Implement共享数据契约与实现。即将契约的定义与实现放在一个程序集,然后供服务端和客户端引用。
Ø Soapsuds通过元数据生成供客户端使用的dll。即将契约的定义与实现放在一个程序集,然后通过通过工具将服务生成一个dll,供客户端引用。
Soapsuds –url:http://localhost:9012/myservice.rem?wsdl –oa:d:\share.dll,在应用此工具的时候,
*然后通过Soapsuds –url:http://localhost:9012/myservice.rem?wsdl –oa:d:\share.dll,
*生成供客户端应用的dll
*/
HttpChannel chnl = new HttpChannel(9012);
ChannelServices.RegisterChannel(chnl, false);
RemotingConfiguration.ApplicationName = "MyServer";
RemotingConfiguration.RegisterWellKnownServiceType(typeof(CAO.ShareDLL.MyService),
"myservice.rem",
WellKnownObjectMode.SingleCall);
Ø Client Object Factory,通过客户端调用服务端的对象工厂,创建服务对象。
契约层:
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace CAO.Factory.ShareDLL
{
public interface IMyService
{
string SayHello(string name);
ICAOObject CreateCAO(string name);
}
public interface ICAOObject
{
string Name { get; set; }
string SayHelloCAO();
}
}
服务端:
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.Remoting;
using System.Runtime.Remoting.Channels;
using System.Runtime.Remoting.Channels.Tcp;
using System.Runtime.Remoting.Channels.Http;
namespace CAO.Factory.Server
{
class Program
{
static void Main(string[] args)
{
TcpChannel chnl = new TcpChannel(9012);
ChannelServices.RegisterChannel(chnl, false);
//SingleCall方式
RemotingConfiguration.RegisterWellKnownServiceType(typeof(MyService),
"myservice.rem",
WellKnownObjectMode.SingleCall);
Console.WriteLine("Server is Running...");
Console.Read();
}
}
public class MyService:MarshalByRefObject,ShareDLL.IMyService
{
public string SayHello(string name)
{
return string.Format("Hello {0}",name);
}
public ShareDLL.ICAOObject CreateCAO(string name)
{
return new MyCAOImpl(name);
}
}
public class MyCAOImpl : MarshalByRefObject, ShareDLL.ICAOObject
{
private string _name;
public string Name
{
get { return _name; }
set { _name = value; }
}
public string SayHelloCAO()
{
return string.Format("Hello {0}", this.Name);
}
public MyCAOImpl(string name)
{
this._name = name;
}
}
}
客户端:
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.Remoting;
using System.Runtime.Remoting.Channels;
using System.Runtime.Remoting.Channels.Tcp;
namespace CAO.Factory.Client
{
class Program
{
static void Main(string[] args)
{
TcpChannel chnl = new TcpChannel();
ChannelServices.RegisterChannel(chnl, false);
ShareDLL.IMyService service = (ShareDLL.IMyService)Activator.GetObject(typeof(ShareDLL.IMyService),
"tcp://localhost:9012/myservice.rem");
ShareDLL.ICAOObject obj1 = service.CreateCAO("mike");
Console.WriteLine(obj1.SayHelloCAO());
Console.Read();
}
}
}
以上是《Framework的架构设计与应用》关于Remoting的读书笔记。全部源代码下载: https://files.cnblogs.com/jackhuclan/RemotingTest.rar,关于更多高深的话题,可以参考:http://www.cnblogs.com/rickie/category/5082.html