Akka / Scala检测到关闭的TCP连接?

时间:2016-03-08 07:41:49

标签: scala akka

我尝试使用Akka和Scala编写TCP服务器,它将实例化actor并在客户端分别连接和断开连接时停止actor。我有一个TCP绑定actor,

 class Server extends Actor{
   import Tcp._
   import context.system

   IO(Tcp) ! Bind(self, new InetSocketAddress("localhost", 9595))

   def receive = {

     case Bound(localAddress) =>
       println("Server Bound")
       println(localAddress)

     case CommandFailed(_: Bind) => context stop self

     case Connected(remote, local)=>
       val handler = context.system.actorOf(Props[ConnHandler])
       val connection = sender()
       connection ! Register(handler)
   }
 }

以上实例化localhost:9595上的TCP侦听器,并将处理程序actor注册到每个连接。

然后我在我的receive类中定义了ConnHandler def,缩写为...,代码行为正确。

case received => {...}
case PeerClosed => {
    println("Stopping")
    //Other actor stopping, cleanup.
    context stop self
}

(有关我曾经写过的文档,请参阅http://doc.akka.io/docs/akka/snapshot/scala/io-tcp.html - 它在PeerClosed案例中使用的代码大致相同)

然而,当我关闭套接字客户端时,该actor仍在运行,并且没有"停止"邮件已打印。

我没有附近配置的非Windows机器来测试这个,因为我相信这与我在Windows上运行有关,因为在谷歌搜索后,我发现了一个仍然开放的bug - https://github.com/akka/akka/issues/17122 - 这指的是一些在基于Windows的系统上错过关闭事件。

我是否在代码中犯了一个愚蠢的错误,或者这是否是上面链接的错误的一部分?

虽然我可以写一个关闭连接的Received(data)的情况,然而,网络断开连接导致的断开连接会使服务器处于不可恢复状态,需要重启应用程序,因为它会在一个说客户端仍然连接的状态下留下一个辅助共享actor,因此,服务器会拒绝该用户的进一步连接。

编辑:

我通过添加一个看门狗定时器actor来解决这个问题,该actor具有在一段时间后触发的定期动作。每次在连接上发生事件时,ConnHandler actor都将重置监视程序计时器。虽然不理想,但它可以做我想做的事。

1 个答案:

答案 0 :(得分:-1)

2016年12月9日编辑: 即使客户端意外断开连接,ConnHandler也会收到PeerClosed消息。