One binded rmi name can be used by Multiple client?

末鹿安然 提交于 2019-12-12 04:23:27

问题


I am trying to run 3 RMI server on Single (96 Ram) Machine. From three different machine clients are calling, but for three clients I have given 3 different port numbers and binded object name are also different for all three client.

For 1st 2 client I got the output and for thirst one I am not getting any output. Only "Null Pointer exception" I am getting on client side. On Server side I have given -Xms250m to -Xmx 20g on all 3 server. On client all have 8 GB ram I have given -Xmx6g.


回答1:


You need to use a customized RMIRegistry port to have two or more registry instances run in a same machine. See this fully working RMI Server and Client example, you can run multiple clients connecting to the same remote object instance. Remember to synchronize internal behaviour of the service implementation.

Here is a remote service interface and implementation run on server machine.

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);
    }   
}

Here is a RMI client and server implementation.

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
    }

}

Here are test scripts to run server and client.

**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


来源:https://stackoverflow.com/questions/38438070/one-binded-rmi-name-can-be-used-by-multiple-client

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!