Zee
Zee

Reputation: 1420

Sending non-ByteString over Tcp Client using Akka IO

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

Answers (1)

johanandren
johanandren

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

Related Questions