David Weber
David Weber

Reputation: 1995

Retrieve the local IP and port from an outbound Akka TCP stream

I am dealing with a server for a rather picky protocol (SIP) that needs my local IP and port as part of the header structure. I am using an Akka TCP stream for its awesomeness but I am missing the equivalent of BSD socket's getsockname function. In Akka actor-oriented connections, the connection sends a convenient message reporting the local IP and port, but I cannot find a way to get this from the Akka Streams version. The stream is connected directly to some flow for further processing, but there is no room for a message containing the IP and port of the local side of the connection.

val connection = Tcp().outgoingConnection("www.google.com", 80)

val test = List("GET / HTTP/1.1", "Host: www.google.com", "\r\n").map(s ⇒ ByteString(s + "\r\n"))
val res = Source(test).via(connection).runFold(ByteString.empty)( _ ++ _ )

// How do I get the connection details here?
res.onComplete{
  case Success(resp) ⇒ println(resp.utf8String)
  case Failure(f) ⇒ println(f)
}    

Any ideas?

Upvotes: 0

Views: 450

Answers (1)

Jeffrey Chung
Jeffrey Chung

Reputation: 19517

Here is the signature for the Tcp().outgoingConnection method:

def outgoingConnection(host: String, port: Int):
  Flow[ByteString, ByteString, Future[OutgoingConnection]]

The materialized value is a Future[OutgoingConnection], and the OutgoingConnection case class has a localAddress member.

To access the materialized value of the outgoing connection, and in turn the local address, use something like the following:

val (res1, res2) =
  Source(test)
    .viaMat(connection)(Keep.right)
    .toMat(Sink.fold(ByteString.empty)(_ ++ _))(Keep.both)
    .run()

res1 onComplete {
  case Success(OutgoingConnection(_, localAddr)) =>
    println(s"local address: ${localAddr}")
  case Failure(f) =>
    println(f)
}

Upvotes: 2

Related Questions