gpt4 book ai didi

java - 从服务器在客户端执行的 spring 双向 rmi 回调

转载 作者:塔克拉玛干 更新时间:2023-11-01 22:56:55 28 4
gpt4 key购买 nike

在服务器端,我有一个 ListenerManager,它会触发对其 Listener 的回调。使用 Spring RmiServiceExporter

导出管理器

在客户端,我有一个由 RmiProxyFactoryBean 创建的管理器代理,以及一个通过此代理向服务器端的管理器注册的 Listener 实现。

到目前为止一切顺利:ListenerManager 被赋予一个Listener 并调用其回调,但是由于监听器只是客户端对象的反序列化副本,回调在服务器端运行,而不是客户端。

如何让 Spring 在服务器端为客户端监听器生成一个代理,以便服务器调用的回调在客户端远程执行?我当然不需要相反方向的另一对(导出商、代理工厂)?

最佳答案

一个纯RMI解决方案:客户端监听对象需要实现java.rmi.server.UnicastRemoteObject .如果是,它的每个方法都会抛出 RemoteException然后当它通过管理器代理传递到服务器时,一切都自动连接起来,服务器端代理上的方法调用到这个监听器是对真实客户端对象的方法的远程调用。

这样就可以了,但更好的办法是能够包装导出对象而不需要特定的父类(super class)。我们可以使用 CGLIB Enhancer 将监听器“代理”为 UnicastRemoteObject 的子类它还实现了服务接口(interface)。这仍然需要目标对象实现 java.rmi.Remote并声明throws RemoteException .

下一步是一个可以导出任意对象的解决方案以远程调用它们的方法,而不需要它们实现 Remote或声明 throws RemoteException .我们必须将此代理与现有的 Spring 基础设施集成,我们可以通过 RmiBasedExporter 的新实现来做到这一点。以 RmiServiceExporter#prepare() 的非注册表位为模型导出我们代理的 RMI stub 和 RmiClientInterceptor.doInvoke(MethodInvocation, RmiInvocationHandler) 的调用部分.我们需要能够获取服务接口(interface)的导出代理实例。我们可以在 Spring 用于明显“导出”非 RMI 接口(interface)的方法上对其进行建模。 Spring代理接口(interface)生成RmiInvocationWrapper对于非 RMI 方法的调用,序列化方法细节和参数,然后在 RMI 连接的远端调用它。

  • 使用 ProxyFactory和一个 RmiInvocationHandler代理目标对象的实现。
  • 使用 RmiBasedExporter 的新实现至 getObjectToExport() , 并使用 UnicastRemoteObject#export(obj, 0) 将其导出.
  • 对于调用处理程序,rmiInvocationHandler.invoke(invocationFactory.createRemoteInvocation(invocation)) , 与 DefaultRemoteInvocationFactory .
  • 处理异常并适当换行以避免看到 UndeclaredThrowableException s.

因此,我们可以使用 RMI 导出任意对象。这意味着我们可以在客户端使用这些对象之一作为 RMI 服务器端对象上的 RMI 方法调用的参数,并且当服务器端的反序列化 stub 调用方法时,这些方法将在客户端。魔法。

关于java - 从服务器在客户端执行的 spring 双向 rmi 回调,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3779134/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com