Я использую ScalaPB для моего компилятора protobuf, который генерирует классы case, парсеры и сериализаторы Scala для моих буферов протокола.Как отправлять и получать сообщения protobuf через Akka Tcp
У меня есть простой протокол protobuf в файле .proto, который был скомпилирован в класс Scala, благодаря ScalaPB.
option java_outer_classname = "MovementProtos";
message Move {
required string direction = 1;
required string mode = 2;
}
Этот файл компилируется и позволяет мне сделать что-то вроде:
val move = Move(direction = "up", mode = "walk")
У меня есть обработку соединения TCP в Akka актер.
class PacketHandler extends Actor {
def receive: Receive = {
case m: Move =>
// successfully matched against Move case class message
case Tcp.Received(data) =>
// didn't match any messages
case _: Tcp.ConnectionClosed =>
context.stop(self)
}
}
Если я отправить сообщение в Move
Protobuf к моему PacketHandler
, он будет успешно соответствовать против моего Move
случае класса с тем, как я написал свой receive
?
Как отправить сообщение Move
protobuf? Скажем, когда он успешно совпадает с сообщением protobuf Move
, он повторяет его.
def receive: Receive = {
case m: Move =>
// successfully matched against Move case class message
// now echo back 'm' over the wire
sender ! Tcp.Write(???)
...
}
У меня нет клиента, чтобы проверить мой PacketHandler
актер, поэтому я использую телнет.
Также было бы полезно узнать, как выглядит кодированное сообщение Move
, чтобы я мог создать свое соединение по telnet и отправить закодированное сообщение по проводу и проверить, будет ли оно декодироваться, когда оно достигнет PacketHandler
.
К сожалению, отправка классов классов Scala для меня не является выбором ... Сериализация с использованием toByteString - это то, что я искал в плане отправки закодированных данных. Смогу ли я сопоставлять с входящими сообщениями? Например, parseFrom ожидает десериализацию заданного определенного типа. Что, если я не обязательно знаю, какой тип сообщения проходит? –
У вас должна быть одна конечная точка с URI для каждого типа сообщения. В противном случае вы можете обернуть каждое сообщение родительским сообщением (общим типом), которое указывает тип сообщения в строке и фактическое сообщение в байтовом поле, а ваша отдельная конечная точка десериализует родительское сообщение и затем десериализует завернутое сообщение на основе строка типа сообщения. protobuf автоматически не определяет тип сообщения. – kliew
Спасибо! Это решение отлично поработало. –