问题
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()
回答1:
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
来源:https://stackoverflow.com/questions/41850528/how-to-clean-up-akka-http-websocket-resources-following-disconnection-and-then-r