Akka Remoting是否支持单向连接?

时间:2013-04-18 22:23:59

标签: android networking client-server netty akka

我在Android设备上运行Akka系统,通过Akka Remoting与服务器上的Akka系统通信。

Android设备可能会获得任何IP地址,IP可能会在应用程序运行时发生变化,并且无法从服务器访问IP。因此,我在Android设备上使用akka.remote.netty.hostname = "0.0.0.0"akka.remote.netty.port = 8000配置了Akka。

Android Akka系统获取对服务器上的actor的引用,向其发送消息,服务器上的Actor记录sender()actorRef并继续向其发送消息。当服务器和Android设备在同一个wlan上,以及当他们通过互联网通过GPRS进行通话时,这种方法都可以使用。

现在我正在仔细研究连接丢失和重新连接。我一直关注的场景是:

  • Android设备和服务器都在wlan上。
  • Android设备向服务器发送消息。
  • Android上的Akka远程处理会生成RemoteClientStarted
  • 服务器上的Akka远程处理会生成RemoteClientStartedRemoteServerClientConnected
  • 然后我在Android上关闭wlan,等待几秒钟然后再打开它。系统之间不会尝试向服务器发送消息。
  • Android上的Akka远程处理产生RemoteClientShutdownRemoteClientError(ETIMEDOUT)
  • Akka远程服务器上没有任何内容。
  • Android向服务器发送消息。
  • 服务器生成RemoteServerClientConnected并收到消息。
  • 服务器尝试向Android发送消息(将其称为 A ),然后生成:RemoteServerErrorRemoteServerClientDisconnectedRemoteClientShutdown,{{ 1}}。
  • Android永远不会从服务器获取消息。
  • 服务器尝试发送另一条消息,但Akkas RemoteServerClientClosed说:
    • [PassiveRemoteClient @ akka://xxx@0.0.0.0:8000]已关闭
    • 启动远程客户端连接到[akka://xxx@0.0.0.0:8000 | /0.0.0.0]
    • RemoteClientError @ akka://vts@0.0.0.0:8000:错误[...

最后一个错误似乎来自于Akka Remote希望创建新的RemoteClient而不是重用现有的ActiveRemoteClient。我想这再次来自于服务器在看到错误/断开连接/关闭/ clientcloseds之前观察RemoteServerClientConnected事件。

现在问题:

  1. 在此方案中,如何在发送消息A时让服务器重用Android设备上的最后一个传入连接(PassiveRemoteClient)?
  2. 如何指示服务器不要尝试连接回客户端?
  3. 版本:

    • Android:15(4.0.3)
    • Akka:2.1
    • Java:1.6 64bits
    • Scala:2.10.1
    • Netty:3.5.8

1 个答案:

答案 0 :(得分:7)

这可能不是你一直希望的答案,但在这里(我是Akka技术主管)。

Akka远程处理旨在在充当同伴的系统之间工作。开发背后的驱动力是构建集群支持,该支持从2.1版开始出现,并且将从2.2开始正式支持并进一步开发。这有一些重要的后果:

  • ActorRefs应该是位置透明的,这意味着无论您在何处使用它们,它们的工作方式都相同,因此每个节点都需要能够连接到给定引用指向的节点。
  • Akka节点之间的通信基本上是对称的,即使您的使用可能不是。
  • 传递ActorRef作为进行对话的方式意味着通过引用指向的实体需要保持可用或通信失败;并且保持可用意味着“在参考所指的同一位置”。

对于您的场景,这意味着您最好不要使用普通的远程处理来耦合您的actor系统,而是使用支持您遭受的短暂关联的其他东西。例如,您可以将服务器公开为REST服务,或者您可以使用Akka IO层使用裸TCP(甚至UDP)。在处理服务器端端点的actor中,您可以识别同一客户端是否从不同的网络位置与您通信,缓冲区回复消息,伪装成本地代理actor后面的外部actor等。使用此方案,您甚至可以构建在不可靠的通道上进行可靠的消息传递(使用ACK),美妙的是在服务器(可能是集群)内,所有通信都能正常工作,因为如何与客户端通信的问题部分被封装在一个位置。

长话短说:你的用例不是普通的Akka远程开发支持的用例。