Reputation: 1420
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.
Upvotes: 1
Views: 556
Reputation: 11479
Over the network there is no such thing as String
or ByteString
, there are only bytes. ByteString
is 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 a ByteString
from a String
it will use an encoding (UTF8
in 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
Upvotes: 0