Java中间件之RMI编程

句柄是一种特殊的智能指针 。当一个应用程序要引用其他系统(如数据库、操作系统)所管理的内存块或对象时,就要使用句柄。

分布式计算时解决大型应用的一种重要手段。它指的是一种应用程序的的设计模式,其中程序数据计算能力都分布在网络中。


RMI(远程方法调用)是不同的java虚拟机之间的对象间进行通信的规范。

远程对象:另外一个虚拟机中对象。这类对象被接口描述,这些接口实现声明了远程对象的方法。

远程方法调用:对一个远程对象中的接口中的方法进行调用。


实现不同JAVA虚拟机之间应用程序之间通信技术区别:


1.套接字,通过应用级协议进行通信,要求应用程序之间必须使用相同协议。

2.JMS(JAVA消息服务),对象在物理上被异步的从网络的某个JVM直接移动到另一个JVM。

3.RMI(远程方法调用),RMI对象是绑定在本地JVM中,只有函数参数和返回值是通过网络传送的。

一个RMI会话系统:
1》定义远程接口
2》实现这个接口
3》生成stub(客户代理)和skeleton(服务器实体)
4》编写远程对象的客户程序

5》启动注册表并登记远程对象

扫描二维码关注公众号,回复: 3288419 查看本文章

6》运行服务器和客户程序


参考博客:http://blog.csdn.net/qq_30114557/article/details/69390714?locationNum=14&fps=1(运行步骤)

(1) 在执行 rmiregistry 之前,设置classpath让能查找到PerfectTime_Stub类,如在同一Dos窗口中,假设 PerfectTime_Stub类是在E:\workspace\TestRMI\bin目录中,执行过程那就是

C:\Documents and Settings\unmi>set classpath=%classpath%;E:\workspace\TestRMI\bin

C:\Documents and Settings\unmi>rmiregistry 2005

有了远程接口及其实现以后,就需要在注册表中对它进行绑定,以使客户能获得该对象。

服务器接口:

package rmiTest;

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

public interface RMITest1I extends Remote{
      long getPerfectTime() throws RemoteException;
}

实现服务器接口的类:

package rmiTest;

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

public class RMITest1  extends UnicastRemoteObject implements RMITest1I{

    public RMITest1() throws RemoteException {
        // TODO Auto-generated constructor stub
        super();
    }

    @Override
    public long getPerfectTime() throws RemoteException {
        // TODO Auto-generated method stub
        return System.currentTimeMillis();
    }
    
    @SuppressWarnings("deprecation")
    public static void main(String[] args){
           try{
               RMITest1 rt=new RMITest1();
               Naming.rebind("rmi://localhost:1099/RMITest1", rt);
               System.out.println("Bind OK!");
               
           }catch(Exception e){
             e.printStackTrace();  
           }
    }

}


客户端代码:

package rmiClient;

import java.rmi.Naming;

import rmiTest.RMITest1I;

public class DisplayPerfectTime {

    public DisplayPerfectTime() {
        // TODO Auto-generated constructor stub
        super();
    }

    public static void main(String[] args) {
        try{
            RMITest1I t=(RMITest1I) Naming.lookup("rmi://localhost:1099/RMITest1");
            for(int i=0;i<10;i++){
                System.out.println("PerfectTime:"+t.getPerfectTime());
            }
        }catch(Exception e){
            e.printStackTrace();
        }
    }

}

带有回调的RMI会话


Java ConcurrentModificationException 异常分析与解决方案(http://www.2cto.com/kf/201403/286536.html)

服务程序

package rmiServer;

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

import rmiClient.RMIClientI;

public interface RMIServerI extends Remote{
     //客户程序应该实现的远程接口
       public void registerClient(RMIClientI client) throws RemoteException;
       public void unregisterClient(RMIClientI client) throws RemoteException;
}

package rmiServer;

import java.rmi.Naming;
import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;
import java.util.HashSet;
import java.util.Iterator;

import rmiClient.RMIClient;
import rmiClient.RMIClientI;

@SuppressWarnings("serial")
public class RMIServer extends UnicastRemoteObject implements RMIServerI,Runnable{

    protected HashSet clients;
    public RMIServer() throws RemoteException {
        // TODO Auto-generated constructor stub
        super();
        clients=new HashSet();
    }
    public void run(){
          for(;;){
            // Iterator iterator=clients.iterator();
            // while(iterator.hasNext()){
                   for( Iterator iterator=clients.iterator();iterator.hasNext();){
                          RMIClientI rmiclient=(RMIClientI) iterator.next();
                          try{
                                 rmiclient.getPerfectTime();
                          }catch(Exception e){
                                 System.out.println("移除对象");
                                 iterator.remove();
                          }
                   }
                            
                   try{
                       Thread.sleep(1000);
                       System.out.println("我想休息1000s!");
                   }catch(Exception e){
                       e.printStackTrace();
                   }
             }
          
    }
    
    public void registerClient(RMIClientI client) throws RemoteException {
        // TODO Auto-generated method stub
          System.out.println("加入客户对象");
          clients.add(client);
        
    }

    public void unregisterClient(RMIClientI client) throws RemoteException {
        // TODO Auto-generated method stub
        System.out.println("删除客户对象");
        clients.remove(client);
    }

    public static void main(String[] args){
        
        try{
            RMIServer server=new RMIServer();
            Naming.rebind("rmi://localhost/RMIServer", server);
            System.out.println("Bind Ok");
            (new Thread(server)).start();
        }catch(Exception e){
            e.printStackTrace();
        }
        
    }

}


客户程序

package rmiClient;

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

public interface RMIClientI extends Remote{
      void getPerfectTime() throws RemoteException;
}

package rmiClient;

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

import rmiServer.RMIServer;
import rmiServer.RMIServerI;

public class RMIClient  extends UnicastRemoteObject implements RMIClientI{

    public RMIClient() throws RemoteException {
        // TODO Auto-generated constructor stub
        super();
    }

    @Override
    public void  getPerfectTime() throws RemoteException {
        // TODO Auto-generated method stub
        System.out.println("PerfectTime:"+System.currentTimeMillis());
    }
    
    @SuppressWarnings("deprecation")
    public static void main(String[] args){
           try{
               RMIClient client=new RMIClient();
               RMIServerI server=(RMIServerI)Naming.lookup("rmi://localhost/RMIServer");
               server.registerClient(client);
               
           }catch(Exception e){
             e.printStackTrace();  
           }
    }

}

回话系统和回调回话系统都需要手工启动服务器,并且客户机要在  服务器程序将服务器对象注册到RMI注册表之后才能使用服务器对象。

RMI激活框架提供了另一种访问服务器对象的方法,即利用特殊安装程序,可以使用激活框架激活服务器对象。

远程对象激活

对象激活就是允许远程对象根据需要被执行。RMI则采用了滞后激活,就是把对象激活操作推迟,直到客户第一次使用该对象,即第一次方法调用。

实现激活功能,在激活框架中有几个相互协作的实体:

*远程对象

*包装程序,用来注册对象。

*激活驻留程序,记录像注册表之类的信息。包装程序向激活系统进行几个方法的调用,以提供应当如何激活对象的有关细节。

一个远程对象被激活的步骤:

*远程对象应当继承java.rmi.activation.Activatable类

*远程对象应当包含一个采用两个参数的特殊的构造函数。激活标识符和激活数据。

*创建一个激活器来描述,并用Activator来注册它。

服务程序:

客户程序:

注册激活程序:

在IIOP上运行RMI

我在中













猜你喜欢

转载自blog.csdn.net/slqSLQSHILIQIANG/article/details/70779886