清泉底上晶莹的翡翠
当男孩变成男人,他多了一份成熟,对自己所爱的女孩,应该给得起承诺。

Remoting入门

前几天接到一个项目,是一个分布式系统。本人从来就没做过分布式系统,凭着几年的开发经验。仔细分析了需求。得出有两个解决方案;一是Webservice.Net Remoting。最后选择了Remoting。至于在这两个技术中如何去选择,网上能找到很多相关资料,我也会在后续的文章写一点。

本文作为一篇入门级的文章,结合自己的经验,和大家一起来认识下Remoting。在这里我们不阐述很多的理论。用一个实际的例子来说明。用remoting大概可以分为这么三步走:

1.  首先建立一个远程对象RemotingObject首先我们建立类库工程RemotingObject。加入一个类文件。加入如下代码:

using System;

using System.Data;

using System.Data.SqlClient;

 

using BeatFate.Data;

 

namespace BeatFate.Data.Remoting.Object

{

     [SerializableAttribute]

    public sealed class DataAccess : MarshalByRefObject

    {

         private string StringValue = "This is the RemotableType.";

         public string StringMethod() {

              return StringValue;

         }

}

}

这里做几点说明:

a.    所有远程对象类必须继承自MarshalByRefObject

b.   如果必要的情况我们必须序列化该类,所以必需加上元属性[SerializableAttribute]

c.    我这个类是用作数据库访问的基类所以引入了我自己的类,和一些相关的数据库类的引用。

2.  建立服务器类。我们可以建立一个WinForm应用程序。在该工程中我们要加入app.config配置文件和一个server类文件两个文件的代码分别是
<?xml version="1.0" encoding="utf-8" ?>

<configuration>

    <system.runtime.remoting>

    <application name="BeatFateService">

       <service>

          <wellknown

            mode="SingleCall"

            type="BeatFate.Data.Remoting.Object.DataAccess,RemotingObject"

            objectUri="DataAccessObject"/>

        </service>

        <channels>

          <channel ref="tcp server" port="9898"/>

        </channels>

      </application>

      <debug loadTypes="true"/>

      <customErrors mode="off"/>

    </system.runtime.remoting>

</configuration>

对配置文件做几个如下注释:

A<application name="BeatFateService">这个name属性可以是任意的当然最好是一个您认为有意义的名字

B<service>

          <wellknown

            mode="SingleCall"

            type="BeatFate.Data.Remoting.Object.DataAccess,RemotingObject"

            objectUri="DataAccessObject"/>

</service>

type="BeatFate.Data.Remoting.Object.DataAccess,RemotingObject"

BeatFate.Data.Remoting.Object.DataAccess整个类的完整名字

RemotingObject程序集名字。

在这里申明了生存期模型。在.NET Remoting

        •客户端激活对象

        •服务器激活对象

        <channels>

          <channel ref="tcp server" port="9898"/>

        </channels>

通道申明在.NET Remoting通道主要有两种:TcpHttp,找一个没有使用的端口注册一个端口
using System;

using System.Collections.Generic;

using System.ComponentModel;

using System.Data;

using System.Drawing;

using System.Text;

using System.Windows.Forms;

 

using System.Runtime.Remoting;

using System.Runtime.Remoting.Channels;

//using System.Runtime.Remoting.Channels.Tcp;

 

namespace Server {

     public partial class Form1 : Form {

         public Form1() {

              InitializeComponent();

              RemotingConfiguration.Configure("Server.exe.config",false);

 

              //      TcpChannel chan = new TcpChannel(8085);

              //      ChannelServices.RegisterChannel(chan);

              //      RemotingConfiguration.RegisterWellKnownServiceType(Type.GetType("RemotingSamples.HelloServer,Object"), "SayHello", WellKnownObjectMode.SingleCall);

         }

     }

}

在框架中注册远程对象时,需要以下四项信息:

        •包含类的程序集名称。

        •远程对象的类型名称。

        •客户端定位对象时将使用的对象 URI

        •服务器激活所需的对象模式。该模式可以是 SingleCall,也可以是 Singleton

3.建立客户端类,我们也可以建立一个WinForm应用程序。在该工程中我们要加入app.config配置文件和一个client类文件两个文件的代码分别是
<?xml version="1.0" encoding="utf-8" ?>

<configuration>

  <!-- .NET Remoting configuration -->

  <system.runtime.remoting>

    <application name="Textile">

      <client>

          <wellknown type="BeatFate.Data.Remoting.Object.DataAccess,RemotingObject" url="tcp://localhost:9898/DataAccessObject" />

      </client>

      <channels>

        <channel ref="tcp client" />

      </channels>

    </application>

  </system.runtime.remoting>

  <appSettings>

    <add key="ServiceURL" value="tcp://localhost:9898/DataAccessObject"/>

  </appSettings>

</configuration>

对这个配置文件我也作一些简单的说明:

A<wellknown type="BeatFate.Data.Remoting.Object.DataAccess,RemotingObject"同前面服务器中的配置文件。

Burl="tcp://localhost:9898/DataAccessObject" />就是服务器地址加上端口号再加上服务器配置文件中申明的objectUri="DataAccessObject"/>

<appSettings>

    <add key="ServiceURL" value="tcp://localhost:9898/DataAccessObject"/>

  </appSettings>

是我自己加上去的,方便程序中读取也方便修改

using System;

using System.Collections.Generic;

using System.ComponentModel;

using System.Data;

using System.Drawing;

using System.Text;

using System.Windows.Forms;

 

using System.Configuration;

using System.Runtime.Remoting;

using System.Runtime.Remoting.Channels;

//using System.Runtime.Remoting.Channels.Tcp;

using BeatFate.Data.Remoting.Object;

 

namespace Client {

     public partial class Form1 : Form {

         public Form1() {

              InitializeComponent();

              string s = "";

 

              //RemotingConfiguration.Configure("Client.exe.config");

              //HelloServer obj = new RemotingSamples.HelloServer();

              Console.WriteLine("开始远程调用");

              DataAccess obj = (DataAccess)Activator.GetObject(typeof(DataAccess), ConfigurationManager.AppSettings["ServiceURL"]);

              System.Console.WriteLine("远程调用的地址:" + ConfigurationManager.AppSettings["ServiceURL"]);

              if (obj == null) System.Console.WriteLine("Could not locate server");

              else s = obj.StringMethod();

         }

     }

}

然后分别在服务器和客户端项目中加入RemotingObject类库的引用。

先运行服务器程序然后再运行客户端程序,服务器和客户端可以运行在同一网络上的不同机器上。当然我上面是用tcp实现所以不能穿透防火墙。

由于时间仓促,很多东西可能都没讲清楚,如果有疑问可以email给我:percypeng2000@126.com来信回复,有时间的话我也会将我理解的东西再进去,当然也希望大家批评指正。这个是在blog园里的处女作,只希望他能给大家带来一定的信息我就很满足了。

posted on 2006-04-12 23:48  感受精彩  阅读(594)  评论(1编辑  收藏  举报