RMI备选方案,用于通过防火墙或NAT进行双向异步调用和回调

时间:2013-02-24 03:53:38

标签: java networking asynchronous architecture rmi

我正在用Java编写基于服务器 - 客户端架构的游戏。

出于设计原因,我想使用异步调用将客户端操作传递给服务器,还使用异步回调将所述操作的结果传递回客户端。异步调用允许缓冲客户端操作。排队缓冲允许简单,基本上是一个线程处理客户端操作。

目前,我的服务器和客户端代码非常对称。他们创建一个注册表,然后导出并绑定自己。

通过在ConcurrentLinkedQueue中缓冲传入的操作或结果来实现异步性。实际处理由定期运行的线程完成。

但是,当客户端防火墙或NAT后面时,此当前架构不起作用。在这种情况下,服务器无法访问客户端以将结果推送给他们。

此外,在此当前体系结构中,服务器不知道哪个客户端发送了给定操作,除非引入了冗余的身份验证或会话处理层。这允许伪造行为和作弊。


我一直在考虑可能的解决方案,但没有找到合适的解决方案:

  • 客户端拉取而不是服务器推送。服务器上可能有一个方法,客户端定期调用以获取其结果。但是,这种方法看起来非常难看,它引入了额外的延迟,带宽和时序问题。也不解决行为伪造。直接通知也是非常受欢迎的。

  • TCP连接本身允许双向通信,并且绝对可以识别客户端,因此RMI或JRemoting 可能被黑客入侵以支持它,但我不知道如何,我我不知道任何现有的解决方案。

  • 消息传递。我不确定消息传递框架是否支持身份验证/会话或客户端标识。我肯定会失去远程方法。

  • 我认为正确的解决方案是找到支持上述所有内容的远程方法调用框架。


简而言之,我正在寻找一种方法:

  • 异步调用服务器或向其发送消息
  • 异步调用客户端或向其传递消息,甚至在防火墙或NAT后面
  • 识别发送操作的客户
  • 最好能够调用方法,而不仅仅是传递消息
  • 保持使用JUnit和Mockito(每台机器多个客户端)轻松测试它的能力

是否有支持这些的远程方法调用框架?哪个最好?

1 个答案:

答案 0 :(得分:5)

我不知道为什么你会坚持使用RMI或类似的东西,因为它的定义是单向的。但我必须学习类似的课程......对于my client-server systems中的一个,我使用RMI和长轮询实现了类似于现在的东西。事实证明这是一个可怕的混乱,只是变得越来越糟。

然后我发现了publish-subscribe框架的精彩世界。这些是构建客户端 - 服务器应用程序的自然方式,无需实现大量自己的管道。此外,这些框架支持自动保持活动,时间同步,会话身份验证和权限,以及许多您不想自己实现的其他内容。

对于我的项目,我删除了我自己的所有工作,并用CometD替换它,它支持Java和浏览器(Javascript)客户端,并且不能更快乐。它肯定会支持您的所有需求 - 从任一方发起的异步通信,客户端标识(以及许多其他功能),以及NAT后面的客户端一旦建立连接就不会成为问题。易于编写测试,整个框架已经扩展到能够处理10万个客户端,这对于RMI来说是不可能的。

我强烈建议你考虑放弃能够远程调用方法的要求。方法本质上是片面的,但它们仍然需要呼叫和返回。使用event-driven programming设计系统要好得多。

更新:我已经转移到了网络应用程序的世界,特别是使用Meteor

相关问题