Hello, Habr!
In the course of the work, the task appeared to create several RMI registries accessible through different network interfaces (local network and Internet). And to my surprise, I really did not find anything on the network on this issue. Therefore, having understood himself, I decided to share the decision with people.
Given
Server with two network interfaces: local and external IP addresses. The interface used by the client and implemented by the server:
public interface Server extends Remote { public String getMessage() throws RemoteException; }
Task
Create two RMI registries, each for its own network interface.
Decision
I’ll just make a reservation that it means that the reader is familiar with the basics of RMI (if not, you can read it
here ,
here and
here ). When you create a registry, it is registered to the address specified in the java.rmi.server.hostname parameter. Therefore, we will set our own hostname value before creating each registry. For access from the Internet, it is important to remember that RMI uses 2 ports: one for the registry, one for the object. Those. It is necessary to open access from the Internet to two ports. If you do not specify a port when creating an object, it will be created on an anonymous port, which may not be available from the Internet. So, the following actions:
- We write implementation of the interface with indication of the port;
- Create a registry for the local network;
- Create an object and register it in the registry;
- We pass to the java.rmi.server.hostname value of the external IP-address;
- Create a registry for the external network on one of the open ports;
- Create an object for the external network on the second of the open ports and register it in the registry;
- Profit.
')
Interface implementation
It is important that in the implementation of the interface, the port is specified in the constructor.
public final class ServerImpl extends UnicastRemoteObject implements Server { public ServerImpl(int port) throws RemoteException { super(port); } @Override public String getMessage() throws RemoteException { return "hello"; } }
Create registries
Registry localRegistry = LocateRegistry.createRegistry(localPort);
We receive two RMI registries, everyone is accessible from the interface. For additional registry isolation, you can also write your own
RMIClientSocketFactory and
RMIServerSocketFactory implementations to set up sockets for listening only to specified addresses. But I leave it for self-study.