How to properly identify and hold client references in RMI callback?
<p>I have a server and several "clients" (servers actually because of callbacks). A client can send a message to another only through the server. For this, the server must:</p>

<ol>
<li>Identify the calling client.</li>
<li>Hold the clients' information and exported object reference so it is able to lookup the recipient.</li>
</ol>

<p>I have read on the Remote Session pattern (<a href="https://stackoverflow.com/questions/13632442/how-to-organize-rmi-client-server-architecture/13635838#13635838">1</a>, <a href="https://stackoverflow.com/questions/15912558/rmi-multiple-clients-one-server-object-for-each-of-them/15913298#15913298">2</a>, <a href="https://stackoverflow.com/questions/14261735/how-a-server-can-make-a-session-with-a-client-in-rmi/14266658#14266658">3</a>) and <a href="https://stackoverflow.com/questions/29284276/how-to-send-a-message-from-server-to-client-using-java-rmi">here</a> and <a href="https://stackoverflow.com/questions/4808392/java-rmi-making-the-client-a-server">here</a>, but I couldn't find the answer I was looking for.</p>

<p>For (1), I see the following options:</p>

<ol>
<li>The client sends its exported object reference during the call to the server.</li>
<li>The client sends some identification information during the call to the server.</li>
<li>The client is identified with <code>getClientHost</code>.</li>
</ol>

<p>The recipient must be sent as some identification information since clients do not hold a reference to each other.</p>

<pre><code>public interface RemoteClient extends Remote {

    void message(String sender, String message);
}

public interface RemoteServer extends Remote {

    void relayMessage(String recipient,       RemoteClient sender,     String msg);
                      // or some identifier?  // or string/identifier?
}

public class RemoteServerImpl extends UnicastRemoteObject implements RemoteServer {

    void relayMessage(String recipient, RemoteClient sender, String msg) {

        RemoteClient recp = lookup(recipient); // See point 2 below
        String sndr = getRepresentation(sender); // See below...
        recp.message(sndr, msg);

       // OR using

       String sndr = getRepresentation(getClientHost());
       // Then sender parameter is not needed
    }
}
</code></pre>

<p>I'm pretty sure <code>getClientHost</code> is not a reliable way of identifying the caller because it can disconnect and reconnect with a different IP, and I'm not sure if there are 2 computer in the same LAN that this method will be able to distinguish between them.</p>

<p>For (2), the options I see are:</p>

<ol>
<li>Keep a <code>Map</code> of the identification information and the clients' exported objects (as mentioned, but not recommended, in one of the above answers).</li>
<li>Keep a <code>Set</code> of client information objects where these objects hold the remote object reference and whatever relevant information.</li>
</ol>

<p>These are updated during login (registration) and logout.</p>

<p>Then <code>lookup</code> takes the information and returns the remote object reference and  <code>getRepresentation</code> is similar to a reverse lookup.</p>

<p>My problem is not to make it work (it's working), it's to make it work correctly. Is there any advantage or preferred way from the above or otherwise?</p>