This post demonstrates a solution for the following use case:
- Connect a server and print all the data received as a UTF8 String.
- Retry connect every 4 seconds
- Terminate on user command
The underlying requirement is gathering data from a Terminal Server, where the serial port is exposed as TCP Server.
src
is created from BroadcastHub, so all instances of flow
are referencing the same instance.
It provides the not-yet-completed Source so flow
reads data from the server.
It terminates flow
when its underlying Promise is completed.
The Future exposed by flow._2
completes when the remote server closes the connection, the server is not accessible or the src
is completed. A special SENTINEL exception is used to detect the last case and
stop the retry loop.
val (flag, src) = Source.maybe[Nothing].toMat(BroadcastHub.sink(2))(Keep.both).run()
val SENTINEL = new IOException("stop")
def make: Unit = {
val tcpFlow = Tcp().outgoingConnection(new InetSocketAddress("127.0.0.1", 2558))
val flow = tcpFlow.runWith(src, Sink.foreach(bs => println(bs.utf8String)))
flow._2.onComplete(_ match {
case Failure(SENTINEL) => //stop
case x@_ => system.scheduler.scheduleOnce(4 seconds)(make)
}
)
}
make //start
StdIn.readLine("Press enter to stop")
flag.failure(SENTINEL)