A client gets a reference (a handle) to a remote object via the method Name.lookup(). But how can that remote object (server) obtain a reference to the client which invoked one of its methods (so that the server can invoke methods on the client)?
It can't, "clients" call "servers", not the other way around. However, the usual way to get around this problem is to make something called an "RMI callback". Basically, you make a "client" *also* provide a remote interface, and send this remote interface to the server, the "server" can then become the client of the "client"... BAM! [My head aspolode!]
It's easier to understand if we name the machines, and provide some example interfaces. Let's say there's two interfaces that extend Remote - one's called "RegisterServer" and one's called "Callback". We have a "server" machine called "A" and a client (or multiple clients) called "B". Code implementing RegisterServer is on machine A, and code implementing Callback is on machine B. The RegisterServer is the normal RMI "server", so it's constantly running. So, the "client" code on machine B starts up, and looks up the RegisterServer using the normal naming.lookup() code. Let's say there's a method on the RegisterServer interface that looks something like - "void register(Callback callback) throws RemoteException". So, the client running on machine B provides a "Callback" implementation (the entire client could implement Callback, or a separate class - in either case, it's got to be a remote object, so it needs to extend UnicastRemoteObject just like a normal "server"). This "Callback" implementation gets passed to the RegisterServer implementation, and the RegisterServer does whatever it needs to with it (usually just adds it to a collection of some kind) and returns. Now, there's some kind of separate thread running on the server that needs "Callback" interfaces to make calls on - so it looks in the collection to see if there are any available. If there are, it calls whatever method that Callback provides, something like "void pokeMe(String data) throws RemoteException" or something. So the server calls the pokeMe method with some data, and since "pokeMe" is a remote method, this ends up sending the data back to the "client". One thing to watch out for - the callback has to be called in a separate thread than the one that is invoked by the client - for example, you can't send a message back to the client through the Callback interface inside the register(Callback callback) method.
Hopefully this helps you understand more about the mechanics of how to do this...
Write once, run anywhere, because there's nowhere to hide! - /. A.C.