4

The code below successfully establishes a websocket connection.

The websockets server (also akk-http) deliberately closes the connection using Andrew's suggested answer here.

The SinkActor below receives a message of type akka.actor.Status.Failure so I know that the flow of messages from Server to Client has been disrupted.

My question is ... How should my client reestablish the websocket connection? Has source.via(webSocketFlow).to(sink).run() completed?

What is best practice for cleaning up the resources and retrying the websocket connection?

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()
Community
  • 1
  • 1
Rob O'Doherty
  • 549
  • 3
  • 14

1 Answers1

3

Try the recoverWithRetries combinator (docs here).

This allows you to provide an alternative Source your pipeline will switch to, in case the upstream has failed. In the most simple case, you can just re-use the same Source, which should issue a new connection.

val wsSource = source via webSocketFlow

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

Note that

  • the attempts = -1 will retry to reconnect indefinetely
  • the partial function allows for more granular control over which exception can trigger a reconnect
Stefano Bonetti
  • 8,973
  • 1
  • 25
  • 44
  • 1
    Thanks Stefano. It does answer my question (at least the part about "retrying"). A detail that I omitted, was that I wanted to retry with slightly different behavior. I have a solution for that now. – Rob O'Doherty Jan 27 '17 at 08:50