Reputation: 712
I am developing a game in Java using RMI for all network communication. RMI allows me to call method on my server, but it is not enough for me. I also want the server to be able to spread message among connected clients.
My clients look up for the server (it's interface extends Remote) and register on it. It allows the server to know who is connected. My clients also implement an interface that extends Remote. Here is some part of my code:
Interfaces declaration:
public interface IServer extends Remote {
void connect(IClient Client) throws RemoteException, ExistingItemException;
//...
}
public interface IClient extends Remote {
public void notify(Notification Notification) throws RemoteException;
//...
}
Server side:
//int RMIPort = 1099, ServerPort = 1100;
IServer Server = new RMIServer();
IServer Proxy = (IServer) UnicastRemoteObject.exportObject(Server, ServerPort);
LocateRegistry.createRegistry(RMIPort).rebind("//" + LocalIP + ":" +
RMIPort + "/xxx", Proxy);
Client side:
//Sets the local reference to IServer and creates the IClient
setInstance(new Client(Login, (IServer) LocateRegistry.getRegistry(RemoteIP).
lookup("//" + RemoteIP + ":" + RMIPort + "/xxx")));
//Gets the IClient and makes it available for the IServer to call notify(...)
Proxy.connect((IClient) (UnicastRemoteObject.exportObject(getInstance(), 0)));
This solution works in local but doesn't when I'm trying to use it through Internet.
I have setup my router to expose my computer to a fix IP address and forward the 1099 and 1100 ports. This solution allow other developers to "lookup" my server and get a valid and usable Proxy, but it doesn't allow them to export their IClient. It seems that the JVM tries to export the object to their local network and the execution stops here.
So, I have tried to pass -Djava.rmi.server.hostname=my-external-IP
JVM argument both local for my server and remote for clients. Doing so, exportObject throws a ConnectException
to the remote ip instead of local one.
Upvotes: 2
Views: 6059
Reputation: 365
There is an alternative:
http://dev.root1.de/projects/simon/wiki#Why-SIMON-is-better-than-
The protocol is not compatible to RMI, but the usage is almost the same. Changing from RMI to SIMON is typically not that hard. I heared from users that switching to SIMON took just 30min.
Upvotes: 2
Reputation: 18430
You might think about alternative solution than using RMI, because I believe it was designed for Intranet applications (i.e. Enterprise application within a local network) not Internet.
I would suggest using a long-running TCP connection between the client and the server so at any moment the server wants to communicate back it just pushes a message to this connection.
In this case, initiating the connection will always be the client task. It is very similar to how mail clients connects to imap or pop3 server.
Upvotes: 0
Reputation: 310840
Forget it. Using callbacks over the Internet requires every client to configure his firewall/NAT box/whatever to allow inbound connections and probable port forwarding. Many of them aren't configurable at all, and many of them are run by net admins who just won't do it.
NB you would also have to export on a fixed port.
Upvotes: 5