当前位置: 首页 > 知识库问答 >
问题:

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

乌翔
2023-03-14

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

 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侦听器,并将处理程序参与者注册到每个连接。

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

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

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

虽然我可以在received(data)的情况下编写关闭连接的代码,但是,由于网络断开或其他原因导致的断开将使服务器处于不可恢复的状态,要求重新启动应用程序,因为它将使一个次要的共享参与者处于表示客户端仍然连接的状态,因此服务器将拒绝来自该用户的进一步连接。

编辑:

我已经通过添加一个看门狗计时器执行器来解决这个问题,该执行器具有在一定时间后触发的周期性操作。每当连接上发生事件时,ConnHandler执行器将重置看门狗计时器。虽然不理想,但它做了我想做的事情。

共有1个答案

漆雕唯
2023-03-14

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

 类似资料:
  • 提前致谢

  • 我一直在使用webflux启动程序()处理spring-boot。我创建了一个返回无限通量的简单控制器。我希望发布者只做它的工作,如果有一个客户端(订阅者)。假设我有一个这样的控制器: 现在,当我尝试运行该代码并使用Chrome访问endpointhttp://localhost:8080/时,就可以看到数据了。但是,当我关闭浏览器时,while-loop将继续,因为没有启动cancel事件。如何

  • 在Akka中有没有什么方法可以像在Erlang中一样用{packet,4}来实现包帧?数据包如下所示:

  • 我已经配置了HAProxy(1.5.4,但我也尝试了1.5.14),以便在TCP模式下平衡5672端口上公开AMQP协议(WSO2 Message Broker)的两台服务器。客户端通过Haproxy创建并使用到AMQP服务器的永久连接。 我更改了客户端和服务器TCP keepalive超时,设置net.ipv4.tcp_keepAlive_time=120(CentOS 7)。 在HAProxy

  • 关闭连接可以通过取消来自服务器逻辑的传入连接流(例如,将其下游连接到sink.canceled并将其上游连接到source.empty)。还可以通过取消IncomingConnection源连接来关闭服务器的套接字。 但考虑到和会在协商新连接时设置一次,我不清楚如何做到这一点:

  • 我正在编写一个使用tcp套接字的服务器/客户端应用程序,我的问题是如何检测半开放连接,我计划使用keep-alive但有些人建议我做我自己的协议,所以我现在的计划是: 在服务器端: 服务器会等待10秒等待客户端发送数据,如果在给定的时间内服务器没有收到客户端的消息,服务器会将客户端标记为断开连接,否则,如果服务器收到客户端的消息,则会重新设置计时器。 我现在的问题是,这样行吗?还是我做错了?还是一