I am using akka-io to create a Tcp Client Actor that communicates with a non-jvm tcp (non-akka) server over a socket. Because akka-io sends ByteString and the program expects a regular String outputted to it, the ByteString message is never processed. A very crude java based approach to this actually works:
override def receive: Receive = {
case ClientTcpActor.Start =>
val socket = new Socket(socketAddress.getHostName, socketAddress.getPort)
val out = new PrintWriter(socket.getOutputStream, true)
out.println("Hello World!")
import java.io.BufferedReader
import java.io.InputStreamReader
val is = socket.getInputStream
val isr = new InputStreamReader(is)
val br = new BufferedReader(isr)
val message = br.readLine
println(s"Message received from the server : $message")
}
I am able to send a message to the tcp port and receive a response back.
However, this akka-io approach doesnt work. Specifically, I never receive data back from the socket because the external application cant process the ByteString sent by the Write object
def receive: PartialFunction[Any, Unit] = {
case CommandFailed(_: Connect) =>
log.info("Connection failed.")
context stop self
case c@Connected(_, _) =>
log.info("Connect succeeded.")
val connection = sender()
connection ! Register(self)
val message = ByteString("hello world")
log.info(s"Sending request message ${message}")
connection ! Write(message)
case Received(data) =>
log.info(data.toString())
case _: ConnectionClosed =>
log.info("Connected is closed!")
case _ =>
log.info("Something else is up.")
}
I also created my own akka-IO server application that processes data on the same port and verified that I was actually sending the message to the port, but the akka server actor was needed to process the decoding of the ByteString
Im hoping this is some easy-fix I'm overlooking.
Over the network there is no such thing as
StringorByteString, there are only bytes.ByteStringis essentially just a wrapper around byte arrays to ensure they are not mutated (as that would then require synchronisation for it to be safe to share between threads/actors). When you create aByteStringfrom aStringit will use an encoding (UTF8in this case) to encode the string into bytes.Can't say what is wrong from the pieces of your code that you included, but there is a complete example client in the docs that may be helpful to compare your code to: http://doc.akka.io/docs/akka/current/scala/io-tcp.html#Connecting