posts - 77, comments - 54, trackbacks - 0, articles - 0
  IT博客 :: 首页 :: 新随笔 :: 联系 :: 聚合  :: 管理

Remoting 分布式应用程序

Posted on 2006-08-16 15:19 东人EP 阅读(459) 评论(0)  编辑 收藏 引用 所属分类: .NET

Remoting 分布式应用程序

      .NET Remoting 可以用于访问另一个应用域中的对象,其体系结构额主要元素:

      远程对象:指运行在服务器上的对象,客户机不能直接调用远程对象上的方法,但是可以根据代理来调用。

      通道:用于客户机和服务器之间的通信。有 TCP HTTP 两种通道协议。

      消息:是为客户机和服务器之间的通信而创建的,消息被发送到通道中,消息中包含的内容:远程对象的信息、被调用的方法名称及所有参数。

      格式标识符:用于定义消息是如何传送到通道中的。

      格式标识符提供者:用于把格式标识符与通道连接起来。

      代理对象:客户机调用的是代理对象上的方法,而不是远程对象上的方法,代理对象包括两种:透明代理对象和真实代理对象。

      消息接收器:是一个截取器对象,在服务器和客户机上都有这样的对象,接收器与通道相联系,真实代理对象使用消息接收器把消息传送到通道中,因此在消息进入通道之前,接收器可以进行截取工作。

      激活器:客户机可以通过激活器在服务器上创建远程对象,或截取一个被激活的服务器对象的代理对象。

      RemotingConfiguration 类:用于配置远程服务器和客户机的实用类。

      ChannelServices 类:是一个实用类,可用于注册并把消息传送到通道中。

见如下简单例子:

远程对象:

      远程对象类继承于 MarshalByRefObject 并且定义了远程的实现方法,形成 Remoting 的装配件 Remoting.dll ,当服务器和客户机程序调用远程对象时需要引用装配件 Remoting.dll.

namespace Remoting

{

    public class HelloServer:MarshalByRefObject

    {

        public HelloServer()

        {

            System.Console.WriteLine("HelloServer activated");

        }

        public String HelloMethod(String name)

        {

            Console.WriteLine(

                "Server Hello.HelloMethod : {0}", name);

            return "Hi there " + name;

        }

    }

}

服务器:必须引用Remoting.dll的装配件,服务器上需要创建一个含有端口号的ServerChannel,这样远程对象就可以使用这个服务器通道了。WellKnownObjectMode.Singleton模式说明为每一个方法调用都创建新的实例,服务器不保存远程对象中的状态。

using System;

using System.Collections.Generic;

using System.Text;

using System.Runtime.Remoting;

using System.Runtime.Remoting.Channels;

using System.Runtime.Remoting.Channels.Tcp;

using System.Runtime.Remoting.Channels.Http;

using Remoting;

 

namespace Server

{

    class Program

    {

        static int Main(string[] args)

        {

            TcpChannel channel1 = newTcpChannel(8085);

            HttpChannel channel2 = newHttpChannel(8086);

 

            ChannelServices.RegisterChannel(channel1, false);

            ChannelServices.RegisterChannel(channel2, false);

 

            RemotingConfiguration.RegisterWellKnownServiceType(typeof(HelloServer), "SayHello", WellKnownObjectMode.Singleton);

            System.Console.WriteLine("Enter Any Key,Exit");

            System.Console.ReadLine();

            return 0;

        }

    }

}

客户机:必须引用Remoting.dll的装配件,这里用到了反射原理,使得透明代理对象看起来象真实对象,实际是在反射机制下对取了真实对象的元数据。透明代理对象使用真实代理对象把消息发送给通道。

using System;

using System.Collections.Generic;

using System.Text;

using System.Runtime.Remoting;

using System.Runtime.Remoting.Channels;

using System.Runtime.Remoting.Channels.Http;

using System.Runtime.Remoting.Channels.Tcp;

using Remoting;

 

namespace Client

{

    class Program

    {

        static void Main(string[] args)

        {

            TcpChannel channel1 = newTcpChannel();

            ChannelServices.RegisterChannel(channel1, false);

             HelloServer obj1 = (HelloServer)Activator.GetObject(typeof(Remoting.HelloServer), "tcp://localhost:8085/SayHello");

            if (obj1 == null)

            {

                System.Console.WriteLine("Could not locate TCP server");

            }

 

             HttpChannel channel2 = newHttpChannel();

            ChannelServices.RegisterChannel(channel2, false);

            HelloServer obj2 = (HelloServer)Activator.GetObject(typeof(Remoting.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();

        }

    }

}

只有注册用户登录后才能发表评论。