如何在断开连接后清理akka-http websocket资源然后重试?

时间:2017-01-25 11:31:24

标签: akka-stream akka-http

以下代码成功建立了websocket连接。

websockets服务器(也是akk-http)故意使用Andrew's suggested answer here关闭连接。

下面的SinkActor会收到类型为akka.actor.Status.Failure的消息,因此我知道从服务器到客户端的消息流已中断。

我的问题是......我的客户应该如何重新建立websocket连接? source.via(webSocketFlow).to(sink).run()已完成?

清理资源和重试websocket连接的最佳做法是什么?

class ConnectionAdminActor extends Actor with ActorLogging {
  implicit val system: ActorSystem = context.system
  implicit val flowMaterializer    = ActorMaterializer()

  private val sinkActor = context.system.actorOf(Props[SinkActor], name = "SinkActor")

  private val sink = Sink.actorRefWithAck[Message](sinkActor, StartupWithActor(self.path), Ack, Complete)

  private val source = Source.actorRef[TextMessage](10, OverflowStrategy.dropHead).mapMaterializedValue {
    ref => {
      self ! StartupWithActor(ref.path)
      ref
    }
  }

  private val webSocketFlow: Flow[Message, Message, Future[WebSocketUpgradeResponse]] =
Http().webSocketClientFlow(WebSocketRequest("ws://localhost:8080"))

  source
    .via(webSocketFlow)
    .to(sink)
    .run()

1 个答案:

答案 0 :(得分:3)

尝试recoverWithRetries组合子(文档here)。

这允许您提供管道将切换到的替代Source,以防上游失败。在最简单的情况下,您可以重复使用相同的Source,这应该发出新的连接。

val wsSource = source via webSocketFlow

wsSource
  .recoverWithRetries(attempts = -1, {case e: Throwable => wsSource})
  .to(sink)

请注意

  • attempts = -1将重试非正式重新连接
  • 部分功能允许更精细地控制哪个异常可以触发重新连接