У меня есть определение актера следующим образом:
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 =>
}
}
Есть родительский субъект, который прослушивает клиентов, которые хотят подключиться к TCP-серверу. После подключения клиента родительский субъект создает экземпляр ClientHandler
и дает ему исходное соединение, чтобы ClientHandler
мог напрямую общаться с подключенным клиентом.
Есть еще один актер, который отправляет уведомления клиентам. Этот субъект ищет клиентов по идентификатору через Connector, который возвращает ActorRef
экземпляру ClientHandler
, а затем отправляет ByteString с помощью оператора !
. Как это:
val clientConn = Connector.getConnection(userId)
clientConn match {
case Some(conn) => conn ! payload
case None =>
}
Я был почти уверен, что всякий раз, когда такое уведомление отправляется, я могу получить его в ClientHandler
, используя case Received(msg)
в блоке become
, но оно не работает. Вместо этого case msg: ByteString
работает, но я не понимаю, почему и в чем разница между этими двумя.
Я прочитал документацию по методу Received
и там написано, что Whenever data are read from a socket...
означает ли это, что метод Received
будет соответствовать только тогда, когда удаленный клиент что-то пишет (потому что он пишет в сокет), но когда другой субъект (в данном случае тот, который работает на той же машине; куда идет эта запись, если не в сокет тоже?) записывает что-то, что case msg: ByteString
будет сопоставлено?