如何在RMI回调中正确识别和保存客户端引用?

我有一个服务器和几个“客户端”(服务器实际上是因为回调)。 客户端只能通过服务器向另一个发送消息。 为此,服务器必须:

  1. 识别呼叫客户端。
  2. 保存客户端的信息并导出对象引用,以便能够查找收件人。

我已经阅读了远程会话模式( 1,2,3 )以及这里和这里 ,但我找不到我想要的答案。

对于(1),我看到以下选项:

  1. 客户端在调用服务器期间发送其导出的对象引用。
  2. 客户端在呼叫服务器期间发送一些标识信息。
  3. 客户端使用getClientHost标识。

收件人必须作为一些身份信息发送,因为客户端不会相互引用。

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

我很确定getClientHost不是识别调用者的可靠方法,因为它可以断开连接并重新连接不同的IP,而且我不确定在同一个局域网中是否有2台计算机可以区分这种方法他们。

对于(2),我看到的选项是:

  1. 保留标识信息和客户端导出对象的Map (如上所述,但不推荐,但在上述答案之一中)。
  2. 保留一Set客户端信息对象,这些对象包含远程对象引用和任何相关信息。

这些在登录(注册)和注销期间更新。

然后lookup获取信息并返回远程对象引用, getRepresentation类似于反向查找。

我的问题不是让它工作(它正在工作),而是让它正常工作。 从上面或其他方面有任何优势或首选方式吗?

您似乎根本不了解远程会话模式。 客户端调用远程方法的会话对象对于客户端是唯一的,因此在后续的会话调用期间没有必要进一步标识自身。 无论客户端发送到登录对象以获取会话的任何信息都可以存储在会话对象中,或者服务器可以自己分配唯一的客户端ID。 会话对象当然也应该包含回调:它是唯一合理的地方。