.NET Remoting开发系列:(一) Remoting基础

 Remoting技术简介

 什么是Remoting

      什么是Remoting,简而言之,我们可以将其看作是一种分布式处理方式。从微软的产品角度来看,可以说Remoting就是DCOM的一种升级,它改善了很多功能,并极好的融合到.Net平台下。Microsoft® .NET Remoting 提供了一种允许对象通过应用程序域与另一对象进行交互的框架。这也正是我们使用Remoting的原因。为什么呢?在Windows操作系统中,是将应用程序分离为单独的进程。这个进程形成了应用程序代码和数据周围的一道边界。如果不采用进程间通信(RPC)机制,则在一个进程中执行的代码就不能访问另一进程。这是一种操作系统对应用程序的保护机制。然而在某些情况下,我们需要跨过应用程序域,与另外的应用程序域进行通信,即穿越边界。

Remoting中是通过通道(channel)来实现两个应用程序域之间对象的通信的。

优点: 

1、能让我们进行分布式开发 
2
Tcp通道的Remoting速度非常快 
3
、虽然是远程的,但是非常接近于本地调用对象 
4
、可以做到保持对象的状态 
5
、没有应用程序限制,可以是控制台,winformiisWindows服务承载远程对象 
缺点: 
1
、非标准的应用因此有平台限制 
2
、脱离iis的话需要有自己的安全机制 

Remoting的模式

服务器/客服端模式

如果实现端对端(Peer-to-Peer)

Remoting 开发过程

Remoting 框架图

远程对象的两个含义:

 操作远程对象

  •      对象运行在远程,客户端向他发送消息。
  •      MarshalByRefObject

   传梯远程对象

  •      将远程的对象拿到本地,或者将本地对象发送过去。
  •      对副本进行操作。
  •      序列化【Serializable

通道(Channels

 一个远程对象使用通道发送和接受消息

  •    服务器选择一个通道来监听请求(request
  •    客服端选择通道来和服务器通讯

Remoting 提供了内置的通道

  • TCP通道(TcpChannel  )HTTP通道(HttpChannel)  
  • 你也可以自己编写自己的通道  

传递参数:

 传递简单类型(int doulbe string enum ………………

 传递可序列化的类型(ArrayList DataSet Hashtable ………………

 传递自定义类型  Serializable  

开发Remoting三步走

1、 远程对象: 
建立类库项目:General 

//HelloServer.cs 
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;
        }
        
public MySerialized GetMySerialized()
        {
            
return new MySerialized(4711);
        }

        
public MyRemote GetMyRemote()
        {
            
return new MyRemote(4712);
        }
    }

//Class1.cs
    [Serializable]
    
public class MySerialized 
    {
        
public MySerialized(int val)
        {
            a 
= val;
        }
        
public void Foo()
        {
            Console.WriteLine(
"MySerialized.Foo called");
        }
        
public int A
        {
            
get
            {
                Console.WriteLine(
"MySerialized.A called");
                
return a;
            }
            
set
            {
                a 
= value;
            }
        }
        
protected int a;
    }
    
public class MyRemote : System.MarshalByRefObject
    {
        
public MyRemote(int val)
        {
            a 
= val;
        }
        
~MyRemote()
        {
            Console.WriteLine(
"MyRemote destructor");
        }
        
public void Foo()
        {
            Console.WriteLine(
"MyRemote.Foo called");
        }
        
public int A
        {
            
get
            {
                Console.WriteLine(
"MyRemote.A called");
                
return a;
            }
            
set
            {
                a 
= value;
            }
        }
        
protected int a;
    }

 Serialization vs MarshalByRefObject (远程对象类型)

 按值列集(Serialization 

  • 得到远程对象的副本。
  • 对副本的操作不影响远程对象。
  • 不论远程对象是Singleton 还是SingleCall

[Serializable]

public class MySerialized{...........}

 按引用列集(MarshalByRefObject

  • 得到远程对象引用,本地创建代理(Proxy
  • 通过(Proxy)对远程对象访问。
  • Singleton记录更改,SingleCall无状态。

 public class MyObject:MarshalByRefObject 

{ ………………… }

 

2、服务端建立控制台项目:Server

  public class Server
    {
        
public static int Main(string [] args) 
        {
            
//1、注册通道
            TcpChannel chan1 = new TcpChannel(8085);
            HttpChannel chan2 
= new HttpChannel(8086);

            ChannelServices.RegisterChannel(chan1);
            ChannelServices.RegisterChannel(chan2);

            
//2、注册远程对象
            RemotingConfiguration.RegisterWellKnownServiceType
                (
                
typeof(HelloServer),
                
"SayHello",
                WellKnownObjectMode.SingleCall  
// 无状态模式
                );
            

            System.Console.WriteLine(
"Press Enter key to exit");
            System.Console.ReadLine();
            
return 0;
        }
} 

WellKnownObjectMode.Singleton 介绍如下:

  • Singleton ( 单实例)  有状态模式

Ø 在服务器端只实例化一次

Ø 以后每次调用都访问同一个实例。不论同一客服端还是不同客服端。

Ø 可以维持状态

  • SingleCall 单调用) 无状态模式

Ø 每次调用都实例化新的实例。

Ø 跟好的支持无状态编程模型。

服务器运行结果: 

 

3、客户端:建立控制台项目:Client

public class Client
    {
        
public static void Main(string[] args)
        {
            
//使用TCP通道得到远程对象
            TcpChannel chan1 = new TcpChannel();
            ChannelServices.RegisterChannel(chan1);
            
//WellKnown激活模式
            HelloServer obj1 = (HelloServer)Activator.GetObject(  
                
typeof(RemotingSamples.HelloServer),
                
"tcp://localhost:8085/SayHello");
            
if (obj1 == null)
            {
                System.Console.WriteLine( 
"Could not locate TCP server");
            }

            
//获取 Serializable 对象
            MySerialized ser = obj1.GetMySerialized();
            
if (!RemotingServices.IsTransparentProxy(ser))
            {
                Console.WriteLine(
"ser is not a transparent proxy");
            }
            ser.Foo();

            
//获取 MarshalByRefObject 对象
            MyRemote rem = obj1.GetMyRemote();
            
if (RemotingServices.IsTransparentProxy(rem))
            {
                Console.WriteLine(
"ser is a transparent proxy");
            }
            rem.Foo(); //在服务器端显示

            System.Console.ReadLine();
        }
    }
 客户端激活模式
View Code 
 RemotingConfiguration.RegisterActivatedClientType(               
                
typeof(RemotingSamples.HelloServer),
                
"tcp://localhost:8080/SayHello");
 ServerRemoteObject.ServerObject serverObj 
= new

客服端运行结果:


 

 

作者:罗敏贵
邮箱:minguiluo@163.com
QQ群:34178394 建群 主要是寻找志同道合的人士一起学习和讨论自己的所学所思
出处:http://luomingui.cnblogs.com/
说明:专注于微软平台项目架构、熟悉设计模式、架构设计、敏捷个人和项目管理。现主要从事WinForm、ASP.NET、等方面的项目开发、架构、管理工作。文章为作者平时里的思考和练习,可能有不当之处,请博客园的园友们多提宝贵意见。
知识共享许可协议本作品采用知识共享署名-非商业性使用-相同方式共享 2.5 中国大陆许可协议进行许可。

原文地址:https://www.cnblogs.com/luomingui/p/2100947.html