多个客户端可以使用一个绑定的rmi名称吗?

时间:2016-07-18 13:31:29

标签: java rmi

我试图在Single(96 Ram)Machine上运行3个RMI服务器。从三个不同的机器客户端调用,但对于三个客户端,我已经给出了3个不同的端口号,并且绑定的对象名称对于所有三个客户端也是不同的。

对于1st 2客户端,我得到了输出,并且为了解渴,我没有得到任何输出。只有"空指针异常"我正在客户端。在服务器端,我在所有3台服务器上都给了-Xms250m到-Xmx 20g。在客户端都有8 GB ram我给了-Xmx6g。

1 个答案:

答案 0 :(得分:1)

您需要使用自定义的RMIRegistry端口才能在同一台计算机上运行两个或多个注册表实例。查看此完全正常工作的RMI服务器和客户端示例,您可以运行连接到同一远程对象实例的多个客户端。请记住同步服务实现的内部行为。

这是在服务器计算机上运行的远程服务接口和实现。

import java.rmi.*;
public interface CounterService extends Remote {
    public void setValue(String value) throws RemoteException;
    public String getValue() throws RemoteException;
}

- - - - - -

import java.rmi.*;
public class CounterServiceImpl implements CounterService {
    private int callCount=0;
    private String name;
    private String value;

    public CounterServiceImpl(String name) {
        this.name=name;
        this.value="";
    }

    public synchronized void setValue(String value) throws RemoteException {
        callCount++;
        this.value=value;
    }

    public synchronized String getValue() throws RemoteException {
        callCount++;
        return String.format("%s (name=%s, callcount=%d)", value, name, callCount);
    }   
}

这是RMI客户端和服务器实现。

import java.util.*;
import java.rmi.*;
import java.rmi.registry.Registry;
import java.rmi.registry.LocateRegistry;
import java.rmi.server.UnicastRemoteObject;
import java.rmi.server.ExportException;

public class RMITest1Client {

    private static Random randomInt = new Random();
    public static int getRandomInt(int min, int max) {
        int range = (max - min) + 1;
        return randomInt.nextInt(range) + min;
    }

    public static void main(String[] args) throws Exception {
        String rmiEndPoint = args[0];
        String serviceName = args[1];
        CounterService counter = (CounterService)Naming.lookup(rmiEndPoint+"/"+serviceName);
        System.out.println("Connected to " + rmiEndPoint+"/"+serviceName);

        for(int idx=0; idx<10; idx++) {
            System.out.println("getValue="+counter.getValue());
            Thread.sleep(getRandomInt(1, 5)*1000);
            counter.setValue( "val"+getRandomInt(100, 999) );
            Thread.sleep(getRandomInt(1, 5)*1000);
        }
    }

}

- - - - - -

import java.rmi.*;
import java.rmi.registry.Registry;
import java.rmi.registry.LocateRegistry;
import java.rmi.server.UnicastRemoteObject;
import java.rmi.server.ExportException;

public class RMITest1Server {

    public static void main(String[] args) throws Exception {
        // create the RMIregistry service
        int port = Integer.parseInt(args[0]);
        Registry registry;
        try {
            System.out.println("RMIRegistry on port " + port);
            registry = LocateRegistry.createRegistry(port);
        } catch (ExportException ex) {
            // registry may already be created by another process,
            // get reference to an existing registry instance.
            System.out.println("Creating registry failed, try to connect an existing registry, ex="+ex.getMessage());
            registry = LocateRegistry.getRegistry(port);
        }

        CounterService counter = new CounterServiceImpl("counter1");
        UnicastRemoteObject.exportObject(counter, port);
        registry.rebind("counter1", counter);

        counter = new CounterServiceImpl("counter2");
        UnicastRemoteObject.exportObject(counter, port);
        registry.rebind("counter2", counter);

        System.out.println("Running...");
        Thread.sleep(30000);

        // close registry objects
        for(String serviceName : registry.list()) {
            try {
                System.out.println("RMIRegistry unbind " + serviceName);
                Remote obj = (Remote)registry.lookup(serviceName);
                UnicastRemoteObject.unexportObject(obj, true); 
            } catch (Exception ex) { } 
            try { registry.unbind(serviceName); } catch (Exception ex) { }
        }
        System.out.println("RMIRegistry closed");
        System.exit(0); // mandatory if RMIRegistry was started in this JVM instance
    }

}

以下是运行服务器和客户端的测试脚本。

**goServer.bat**
@SET /p port=Server port (2222, 3333, 0=exit): 
@IF "0"=="%port%" GOTO :EOF
java -cp "./lib/*;" RMITest1Server %port%
pause

- - - - - -

**goClient.bat**
@SET /p port=Server port (2222, 3333, 0=exit): 
@IF "0"=="%port%" GOTO :EOF
@SET /p service=Service index (1,2): 
java -cp "./lib/*;" RMITest1Client rmi://127.0.0.1:%port% counter%service%
pause