??xml version="1.0" encoding="utf-8" standalone="yes"?>美日韩免费视频,亚洲电影在线,欧美日韩综合在线http://www.aygfsteel.com/table/category/41235.htmlzh-cnWed, 12 Aug 2009 11:56:28 GMTWed, 12 Aug 2009 11:56:28 GMT60RMI实用教程http://www.aygfsteel.com/table/articles/290697.htmlTue, 11 Aug 2009 09:50:00 GMThttp://www.aygfsteel.com/table/articles/290697.htmlhttp://www.aygfsteel.com/table/comments/290697.htmlhttp://www.aygfsteel.com/table/articles/290697.html#Feedback0http://www.aygfsteel.com/table/comments/commentRss/290697.htmlhttp://www.aygfsteel.com/table/services/trackbacks/290697.htmlJava Remote Method Invocation ( RMI -- Javaq程Ҏ调用)允许您用Java~写分布式对象。本文将介绍RMI的优点以及如何将其连接到现有的和原有的系l中Q以及与用Java ~写的组件的q接Q同时给Z一个详l的例子Q可以给初学者提供一个学习范本。  

一、RMIQ远E方法调用)的组?/font>

      一个正常工作的RMIpȝ׃面几个部分组成:

      1、远E服务的接口定义
      2、远E服务接口的具体实现
      3、桩QStubQ和框架QSkeletonQ文?
      4、一个运行远E服务的服务?
      5、一个RMI命名服务Q它允许客户端去发现q个q程服务
      6、类文g的提供者(一个HTTP或者FTP服务器)
      7、一个需要这个远E服务的客户端程?


二、RMIQ远E方法调用)的工作原?

RMIpȝl构Q在客户端和服务器端都有几层l构?
--------- ----------
| 客户 | | 服务器|
---------- ----------
| |
------------- ----------
| 占位E序 | | 骨干|?|
-------------- -----------
| |
------------------------------------
| q?E????|
------------------------------------
| |
------------------------------------
| ???|
------------------------------------

     Ҏ调用从客户对象经占位E序QStub)、远E引用层(Remote Reference Layer)和传输层QTransport LayerQ向下,传递给LQ然后再ơ经?输层Q向上穿q远E调用层和骨q网QSkeletonQ,到达服务器对象?占位E序扮演着q程服务器对象的代理的角Ԍ使该对象可被客户ȀzR?q程引用层处理语义、管理单一或多重对象的通信Q决定调用是应发往一个服务器q是多个。传输层理实际的连接,q且q追t可以接受方法调用的q程对象。服务器端的骨干|完成对服务器对象实际的Ҏ调用Qƈ获取q回倹{返回值向下经q程引用层、服务器端的传输层传递回客户端,再向上经传输层和q程调用层返回。最后,占位E序获得q回倹{?

      要完成以上步骤需要有以下几个步骤Q?

      1、生成一个远E接?
      2、实现远E对?服务器端E序)
      3、编写服务器E序 、注册远E对象、启动远E对?br />       4、编写客L?
在JDK1.5之后Q用java提供的API会更加的简单,可以参照下面的例子;

三、例?/p>

1、远E接?/p>

接口名:com.liuxiang.rmi.download.IRMI

该接口定义了一个方法,用于提供q程服务Q?/p>

 

/**
 *
 */
package com.liuxiang.rmi.download;

import java.rmi.Remote;
import java.rmi.RemoteException;

/**
 * q程对象接口
 * @author liuxiang
 * 2007-8-30 下午09:39:15   
 *
 */
public interface IRMI extends Remote{
    public Object invoke(ITask task) throws RemoteException;
}

2、实现远E对?服务器端E序)

cdQcom.liuxiang.rmi.download.IRMIImpl

实现了远E接口定义的ҎQ该实现q程对象中,调用了传入参数的task.doWork()ҎQ同时执行一个本地调用,调用一个播放Mp3的代码段ProcessCaller.callMp3();


 

/**
 *
 */
package com.liuxiang.rmi.download;

import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;

import com.liuxiang.callwindow.ProcessCaller;

/**
 * q程对象的实?br />  * @author liuxiang
 * 2007-8-30 下午09:41:32   
 *
 */
public class IRMIImpl extends UnicastRemoteObject implements IRMI {

    protected IRMIImpl() throws RemoteException {
        super();
    }

    /**
     *
     */
    private static final long serialVersionUID = 6131922116577454476L;

    /* (non-Javadoc)
     * @see com.liuxiang.rmi.download.IRMI#invoke(com.liuxiang.rmi.download.ITask)
     */
    public Object invoke(ITask task) throws RemoteException {
        System.out.println("注意Q这是一个远E调?);
        Object obj = task.doWork();
        System.out.println("调用ITask.doWork()Ҏ的返回|"+obj.toString());
        //客户端调用,可以在服务器端播N要的音乐
        ProcessCaller.callMp3();
        return obj;
    }

}


3、播放Mp3代码D늚源代码如下:

 

/**
 *
 */
package com.liuxiang.callwindow;

/**
 * 在java中调用windowsE序
 * @author liuxiang 2007-8-30 下午10:26:20
 *
 */
public class ProcessCaller {
    /**
     * 调用WindowsE序
     * 利用Windows Media Player播放mp3音乐
     */
    public static void callMp3() {
        Runtime ru = Runtime.getRuntime();
        try {
            // 调用播放器文件播放指定MP3
            Process p1 = ru
                    .exec("C:\Program Files\Windows Media Player\wmplayer F:/music/lx/刘若?后来.mp3");
        } catch (Exception e) {

        }
    }

    /**
     * @param args
     */
    public static void main(String[] args) {
        callMp3();
    }

}

4、Q务接?/p>

该接口定义了q程Ҏ需要传递的参数


 

/**
 *
 */
package com.liuxiang.rmi.download;

import java.io.Serializable;

/**
 * d接口
 * @author liuxiang
 * 2007-8-30 下午09:35:53   
 *
 */
public interface ITask extends Serializable{
    public Object doWork();
}


5、Q务接口实?/p>

该实现定义了q程Ҏ需要传递的参数

 

package com.liuxiang.rmi.download;

/**
 * d实现c?br />  * @author liuxiang
 * 2007-8-31 上午09:08:57   
 *
 */
public class TaskImpl implements ITask{

    public Object doWork() {
        System.out.println("当前E序处于q程调用?);
        return "动态上载对象的q回?;
    }
   
}

6、编写服务器E序 、注册远E对象、启动远E对?/p>

代码Q远E对象的注册c?该类应该在服务器端执?执行之后Q?该机器将变ؓRMI服务?客户端可以通过正确的url来访问;服务器上的远E对象;执行对外报露的方?/p>

 

/**
 *
 */
package com.liuxiang.rmi.download;

import java.rmi.Naming;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;

/**
 * q程对象的注册类 该类应该在服务器端执?执行之后Q?br />  * 该机器将变ؓRMI服务?客户端可以通过正确的url来访?br />  * 服务器上的远E对象;执行对外报露的方?br />  *
 * @author liuxiang 2007-8-30 下午09:44:54
 *
 */
public class RMIServer {
    /**
     * 如果没有创徏一个RegistryQNaming是不会帮助你创徏的?q是自己手工创徏的比较的?br />      *
     * 量用下面的自己装的bindҎ来注册远E对?br />      *
     * @throws Exception
     */
    public static void registRemoteObject() throws Exception {
        IRMIImpl impl = new IRMIImpl();
        Naming.rebind("rmi://219.233.8.97:1111/mytask", impl);
        System.out.println("bound success!");
    }

    /**
     * 创徏一个Registry对象
     *
     * @return q回一个Registry对象
     */
    private static Registry createRegistry() {
        Registry registry = null;
        int port = 1111;
        try {
            registry = LocateRegistry.getRegistry(port);
            registry.list();
            System.out.println("Register the exist server!");
        } catch (final Exception e) {
            try {
                registry = LocateRegistry.createRegistry(port);
                System.out.println("Register the exist server!port=" + port);
            } catch (final Exception ee) {
                ee.printStackTrace();
            }
        }
        return registry;
    }

    /**
     * 对象注册到rmi服务器上
     */
    public static void bind() {
        Registry registry = null;
        registry = createRegistry();
        try {
            IRMIImpl impl = new IRMIImpl();
            registry.rebind("mytask", impl);
            System.out.println("mytask server start!");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * @param args
     */
    public static void main(String[] args) {
        try {
            bind();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

}

q行该服务端代码后,会注册一个远E服务对象,通过恰当的URL可以讉Kq程对象中的ҎQ运行后的结果如下:

Register the exist server!port=1111
mytask server start!

7、编写客L?/font>

代码首先获取一个远E对象,然后如同本地调用一P调用q程对象中的Ҏ?/font>

 

/**
 *
 */
package com.liuxiang.rmi.download;

import java.rmi.Naming;

/**
 * @author liuxiang
 * 2007-8-30 下午09:47:41   
 *
 */
public class RMIClient {
    /**
     * 调用q程对象中的Ҏ
     * @throws Exception
     */
    public static void getRemoteObject() throws Exception{
        IRMI obj = (IRMI)Naming.lookup("rmi://localhost:1111/mytask");    //得到q程发布的服?br />         TaskImpl task = new TaskImpl();
        Object result = obj.invoke(task);    //调用q程服务的方?br />         System.out.println(result.toString());
    }

    /**
     * @param args
     */
    public static void main(String[] args) {
        try {
            getRemoteObject();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

}

最后,q行客户端代码,可以看到控制台分别输Z如下的内容:

Server端输Z更多的内容,如下Q?/font>

 

Register the exist server!port=1111
mytask server start!
注意Q这是一个远E调?br /> 当前E序处于q程调用?br /> 调用ITask.doWork()Ҏ的返回|动态上载对象的q回?
同时可以看到Q会调用了Windows的Mediaplay播放本地盘的Mp3歌曲Q?/font>

Client端输入了如下内容Q?/font>

 

动态上载对象的q回?br />  
四、RMI介绍

RMIQRemote Method InvocationQ远E方法调用)是用Java在JDK1.1中实现的Q它大大增强了Java开发分布式应用的能力。Java作ؓ一U风靡一时的|络开发语aQ其巨大的威力就体现在它强大的开发分布式|络应用的能力上Q而RMI是开发百分之癄Java的网l分布式应用pȝ的核心解x案之一。其实它可以被看作是RPC的Java版本。但是传lRPCq不能很好地应用于分布式对象pȝ。而Java RMI 则支持存储于不同地址I间的程序对象之间彼此q行通信Q实现远E对象之间的无缝q程调用?nbsp;

RMI目前使用Javaq程消息交换协议JRMPQJava Remote Messaging ProtocolQ进行通信。JRMP是专为Java的远E对象制定的协议。因此,Java RMIhJava?Write Once,Run Anywhere"的优点,是分布式应用pȝ的百分之癄Java解决Ҏ。用Java RMI开发的应用pȝ可以部v在Q何支持JREQJava Run Environment JavaQ运行环境)的^C。但׃JRMP是专为Java对象制定的,因此QRMI对于用非Java语言开发的应用pȝ的支持不뀂不能与用非Java语言书写的对象进行通信?

RMI为采用Java对象的分布式计算提供了简单而直接的途径。这些对象可以是新的Java对象Q也可以是围l现有API的简单的Java包装E序。Java体现?#8220;~写一ơ就能在M地方q行的模式。而RMI可将Java模式q行扩展Q之可在Q何地方运?#8221;?

  因ؓRMI是以Java为核心的Q所以,它将Java的安全性和可移植性等强大功能带给了分布式计算。您可将代理和梢?务逻辑{属性移动到|络中最合适的地方。如果您要扩展Java在系l中的用,RMI您充分利用其强大功能?

  RMI可利用标准Java本机Ҏ接口JNI与现有的和原有的pȝ相连接。RMIq可利用标准JDBC包与现有的关pL据库q接。RMI/JNI和RMI/JDBC相结合,可帮助您利用RMI与目前用非Java语言的现有服务器q行通信Q而且在您需要时可扩展Java在这些服务器上的使用。RMI可帮助您在扩展用时充分利用Java的强大功能?/font>

 



2009-08-11 17:50 发表评论
]]>
RMI基础教程http://www.aygfsteel.com/table/articles/290695.htmlTue, 11 Aug 2009 09:44:00 GMThttp://www.aygfsteel.com/table/articles/290695.htmlhttp://www.aygfsteel.com/table/comments/290695.htmlhttp://www.aygfsteel.com/table/articles/290695.html#Feedback0http://www.aygfsteel.com/table/comments/commentRss/290695.htmlhttp://www.aygfsteel.com/table/services/trackbacks/290695.html   RMI的基是接口,RMI构架Z一个重要的原理Q定义接口和定义接口的具体实现是分开的。下面我们通过具体的例子,建立一个简单的q程计算服务和用它的客L?br /> 一个正常工作的RMIpȝ׃面几个部分组成: 
  • q程服务的接口定?
  • q程服务接口的具体实?
  • Stub ?nbsp;Skeleton 文g
  • 一个运行远E服务的服务?
  • 一个RMI命名服务Q它允许客户端去发现q个q程服务
  • cL件的提供者(一个HTTP或者FTP服务器)
  • 一个需要这个远E服务的客户端程?

  •   下面我们一步一步徏立一个简单的RMIpȝ。首先在你的机器里徏立一个新的文件夹Q以便放|我们创建的文gQؓ了简单v见,我们只用一个文件夹存放客户端和服务端代码,q且在同一个目录下q行服务端和客户端?br />   如果所有的RMI文g都已l设计好了,那么你需要下面的几个步骤ȝ成你的系l:
      1?nbsp; ~写q且~译接口的Java代码
      2?nbsp; ~写q且~译接口实现的Java代码
      3?nbsp; 从接口实现类中生?nbsp;Stub ?nbsp;Skeleton cL?br />   4?nbsp; ~写q程服务的主q行E序
      5?nbsp; ~写RMI的客LE序
      6?nbsp; 安装q且q行RMIpȝ

    我的E序是在NetBeans IDE 5.5和JDK1.6下编写的Q当然运行是在命令提C符下进行的


    1、接?br /> W一步就是徏立和~译服务接口的Java代码。这个接口定义了所有的提供q程服务的功能,在这里我们所有完成的是加减乘除Q下面是源程序:

    1. package rmiDemo;
    2. //Calculator.java
    3. //define the interface
    4. import java.rmi.Remote;
    5. public interface Calculator extends Remote
    6. {
    7.     public long add(long a, long b) 
    8.         throws java.rmi.RemoteException
    9.     public long sub(long a, long b) 
    10.         throws java.rmi.RemoteException
    11.     public long mul(long a, long b) 
    12.         throws java.rmi.RemoteException
    13.     public long div(long a, long b) 
    14.         throws java.rmi.RemoteException

    注意Q这个接口承自RemoteQ每一个定义的Ҏ都必LZ个RemoteException异常对象?br /> 建立q个文gQ把它存攑֜刚才的目录下Qƈ且编译?br />
    2、接口的具体实现

      下一步,我们p写远E服务的具体实现Q这是一个CalculatorImplcLӞ

    1. package rmiDemo;
    2. //CalculatorImpl.java
    3. //Implementation
    4. import java.rmi.server.UnicastRemoteObject;
    5. public class CalculatorImpl extends UnicastRemoteObject implements Calculator 
    6.     // q个实现必须有一个显式的构造函敎ͼq且要抛Z个RemoteException异常 
    7.     public CalculatorImpl() 
    8.         throws java.rmi.RemoteException { 
    9.         super(); 
    10.     } 
    11.     public long add(long a, long b) 
    12.         throws java.rmi.RemoteException { 
    13.         return a + b; 
    14.     } 
    15.     public long sub(long a, long b) 
    16.         throws java.rmi.RemoteException { 
    17.         return a - b; 
    18.     } 
    19.     public long mul(long a, long b) 
    20.         throws java.rmi.RemoteException { 
    21.         return a * b; 
    22.     } 
    23.     public long div(long a, long b) 
    24.         throws java.rmi.RemoteException { 
    25.         return a / b; 
    26.     } 

      q个实现cM用了UnicastRemoteObject去联接RMIpȝ。在我们的例子中Q我们是直接的从UnicastRemoteObjectq个cMl承的,事实上ƈ不一定要q样做,如果一个类不是从UnicastRmeoteObject上承,那必M用它的exportObject()Ҏ去联接到RMI?br />   如果一个类l承自UnicastRemoteObjectQ那么它必须提供一个构造函数ƈ且声明抛Z个RemoteException对象。当q个构造函数调用了super()Q它久激zUnicastRemoteObject中的代码完成RMI的连接和q程对象的初始化?br /> 3、Stubs 和Skeletons

      下一步就是要使用RMI~译器rmic来生成桩和框架文Ӟq个~译q行在远E服务实现类文g上?br />        在IDE中build所有程?br />   >rmic rmiDemoCalculatorImpl

      在你的目录下q行上面的命令,成功执行完上面的命o你可以发C个Calculator_stub.class文gQ如果你是用的Java2SDKQ那么你q可以发现Calculator_Skel.class文g?br />
      4、主机服务器

      q程RMI服务必须是在一个服务器中运行的。CalculatorServercL一个非常简单的服务器?br />

    1. package rmiDemo;
    2. //CalculatorServer.java
    3. import java.rmi.Naming;
    4. public class CalculatorServer {
    5.    public CalculatorServer() {
    6.      try {
    7.        Calculator c = new CalculatorImpl();
    8.        Naming.rebind("rmi://localhost:1099/CalculatorService", c);
    9.      } catch (Exception e) {
    10.        System.out.println("Trouble: " + e);
    11.      }
    12.    }
    13.    public static void main(String args[]) {
    14.      new CalculatorServer();
    15.    }
    16. }

      5、客L

      客户端源代码如下Q?br />

    1. package rmiDemo;
    2. //CalculatorClient.java
    3. import java.rmi.Naming
    4. import java.rmi.RemoteException
    5. import java.net.MalformedURLException
    6. import java.rmi.NotBoundException
    7. public class CalculatorClient { 
    8.     public static void main(String[] args) { 
    9.         try { 
    10.             Calculator c = (Calculator)
    11.                            Naming.lookup(
    12.                  "rmi://localhost
    13.                         /CalculatorService"); 
    14.             System.out.println( c.sub(4, 3) ); 
    15.             System.out.println( c.add(4, 5) ); 
    16.             System.out.println( c.mul(3, 6) ); 
    17.             System.out.println( c.div(9, 3) ); 
    18.         } 
    19.         catch (MalformedURLException murle) { 
    20.             System.out.println(); 
    21.             System.out.println(
    22.               "MalformedURLException"); 
    23.             System.out.println(murle); 
    24.         } 
    25.         catch (RemoteException re) { 
    26.             System.out.println(); 
    27.             System.out.println(
    28.                         "RemoteException"); 
    29.             System.out.println(re); 
    30.         } 
    31.         catch (NotBoundException nbe) { 
    32.             System.out.println(); 
    33.             System.out.println(
    34.                        "NotBoundException"); 
    35.             System.out.println(nbe); 
    36.         } 
    37.         catch (
    38.             java.lang.ArithmeticException
    39.                                       ae) { 
    40.             System.out.println(); 
    41.             System.out.println(
    42.              "java.lang.ArithmeticException"); 
    43.             System.out.println(ae); 
    44.         } 
    45.     } 

      保存q个客户端程序到你的目录下(注意q个目录是一开始徏立那个,所有的我们的文仉在那个目录下Q?br />          在IDE中build所有程序?br />   6、运行RMIpȝ

      现在我们建立了所有运行这个简单RMIpȝ所需的文Ӟ现在我们l于可以q行q个RMIpȝ啦!来n受吧?br />
      我们是在命o控制Cq行q个pȝ的,你必d启三个控制台H口Q一个运行服务器Q一个运行客LQ还有一个运行RMIRegistry?br />
      首先q行注册E序RMIRegistryQ你必须在包含你刚写的类的那么目录下q行q个注册E序?br />
      >rmiregistry

      好,q个命o成功的话Q注册程序已l开始运行了Q不要管他,现在切换到另外一个控制台Q在W二个控制台里,我们q行服务器CalculatorServiceQ因为RMI的安全机制将在服务端发生作用,所以你必须增加一条安全策略。以下是对应安全{略的例?nbsp;
    grant {
    permission java.security.AllPermission "", "";
    };

      注意:q是一条最单的安全{略,它允怓Q何h做Q何事,对于你的更加关键性的应用,你必L定更加详l安全策略?br />
      现在Zq行服务端,你需要除客户c?CalculatorClient.class)之外的所有的cL件。确认安全策略在policy.txt文g之后,使用如下命o来运行服务器?br />
      > java -Djava.security.policy=C:\Documents and Settings\Administrator\RMI\build\classes\  rmiDemo.CalculatorServer

      q个服务器就开始工作了Q把接口的实现加载到内存{待客户端的联接。好现在切换到第三个控制収ͼ启动我们的客L?br />
      Z在其他的机器q行客户端程序你需要一个远E接?Calculator.class) 和一个stub(CalculatorImpl_Stub.class)?nbsp;使用如下命oq行客户?br />
       > java -Djava.security.policy=C:\Documents and Settings\Administrator\RMI\build\classes\ rmiDemo. CalculatorClient

      如果所有的q些都成功运行,你应该看C面的输出Q?br />   1
      9
      18
      3



  • 2009-08-11 17:44 发表评论
    ]]>
    վ֩ģ壺 | | | | | | | Ϫ| ʡ| | | | | | | ̩| | ͷ| ߮| | | ˫| | | | ɽ| ƾ| ƽ| ϰ| | | ī| Ǧɽ| Դ| | ƽ| ͬ| ѷ| | | ˮ|