星辉

星月同辉 e路随行
.net/vs2005/c#/web/ajax
  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

初步认识Remoting

Posted on 2007-11-25 22:57  star163  阅读(445)  评论(0编辑  收藏  举报
什么是Remoting
   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;
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;
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;
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)
      则每个段既是服务器又是客户端