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

Java 如何在RMI回调中正确识别和保存客户端引用?,java,rmi,Java,Rmi,我有一个服务器和几个“客户机”(服务器实际上是因为回调)。客户端只能通过服务器向另一个客户端发送消息。为此,服务器必须: 识别呼叫客户机 保存客户端信息和导出的对象引用,以便能够查找收件人 我已经阅读了远程会话模式(,)和,但是我找不到我想要的答案 对于(1),我看到以下选项: 客户端在调用期间将其导出的对象引用发送到服务器 客户端在调用期间向服务器发送一些标识信息 客户端由getClientHost标识 收件人必须作为一些身份信息发送,因为客户端之间没有相互的引用 public interfa

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

  • 识别呼叫客户机
  • 保存客户端信息和导出的对象引用,以便能够查找收件人
  • 我已经阅读了远程会话模式(,)和,但是我找不到我想要的答案

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

  • 客户端在调用期间将其导出的对象引用发送到服务器
  • 客户端在调用期间向服务器发送一些标识信息
  • 客户端由
    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,而且我不确定同一LAN中是否有两台计算机,该方法是否能够区分它们

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

  • 保留标识信息和客户导出对象的
    映射图
    (如上述答案之一所述,但不推荐)
  • 保留一组客户机信息对象,这些对象保存远程对象引用和任何相关信息
  • 这些在登录(注册)和注销期间更新

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


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

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

    在我的问题中,我没有尝试使用远程会话模式,我只是提到我阅读了使用回调的答案,还有2个没有。我的代码只是我试图实现的功能的一个示例实现。我在问,在这些不同的选择中,是否有一个更可取/有利的选择。因此,如果您推荐远程会话模式而不是其他方法,您是否愿意指出它的优点,或者其他方法有什么问题?这是您问题的答案,因为它完全解决了问题,在第一次调用之后,每次调用都不需要额外的参数,此外,它还具有其他优势,如可强制执行的会话过期、死客户端检测等。注意:如果您的客户端在注册回调后更改其IP地址,那么回调无论如何都不会起作用,因此这不是对
    getClientHost()
    的唯一反对意见。如果您可以展开讨论“进一步的优势,如可强制执行的会话到期、死客户端检测等。”在您的回答中,我很乐意接受它,因为它将通过显示这是解决问题的首选方法来回答我的问题。NB是
    getClientHost()
    考虑到两个客户端可以通过同一网关或代理连接,通常是唯一标识调用方的可靠方法?这些都在参考文献(1,2,3)中介绍。
    getClientHost()
    通过
    Socket.getRemoteAddress()标识对等方
    和朋友们,是的,这是受限制的。请原谅我打断一下。我有一个类似的问题,我不理解回调的部分。当你说“会话对象当然也包含回调”时,服务器会话对象(公开服务器方法的对象)以什么方式是否包含回调?是否有其他会话对象公开客户端方法?也许您可以添加一个代码示例?