0

I have an actor definition as follows:

class ClientHandler(connection: ActorRef) extends Actor {

  def receive = {
    case Received(data) => {

      val clientId = data.utf8String.stripLineEnd
      Connector.saveConnection(clientId, self)

      context.become {

       case msg: ByteString => connection ! Write(msg)   

       case Received(msg) => connection ! Write(msg)

      }

    }
    case None =>
  }

}

There is a parent actor that is listening for clients that want to connect to a TCP server. Once a client connects, the parent actor instantiates a ClientHandler and gives it the original connection so that the ClientHandler can talk to the connected client directly.

There is another actor that pushes notifications to clients. That actor looks up clients by ID via Connector that returns an ActorRef to an instance of ClientHandler and then sends a ByteString using the ! operator. Like this:

val clientConn = Connector.getConnection(userId)
clientConn match {
  case Some(conn) => conn ! payload
  case None =>
}

I was pretty sure that whenever such a notification is pushed I can receive it in ClientHandler using the case Received(msg) within the become block, but it didn't work. Instead the case msg: ByteString works, but I don't understand why and what the difference between those two is.

I read the documentation for the Received method and it says Whenever data are read from a socket... does it mean that the Received method will be matched only when the remote client writes something (because he writes to a socket), but when another actor (in this case one that is running on the same machine; where does this write go if not to a socket too?) writes something the case msg: ByteString will be matched?

koleS
  • 1,263
  • 6
  • 30
  • 46
  • 2
    Have you seen https://stackoverflow.com/a/33748534/4982884 (esp points 3 & 4)? – Jeremy Stone Oct 31 '18 at 08:56
  • Probably you should treat them differently as they have different meanings. `Received` is when the client received data from the remote, but `msg: ByteString` is when you wanna send data to the remote. Maybe read the [docs](https://doc.akka.io/docs/akka/2.5/io-tcp.html?language=scala) one more time? – Nader Ghanbari Oct 31 '18 at 23:16
  • 1
    @NaderGhanbari The docs on TCP doesn't describe what `Received` and `data: ByteString` in either "connecting" or "accepting connections" do. I thought `Received` would be used for receiving messages from the remote and from other actors. Apparently when using a TCP actor `Received` is triggered only upon receiving something from the remote and `msg: ByteString` when receiving a `ByteString` from another actor. – koleS Nov 02 '18 at 16:15

0 Answers0