1) Для правильного использования метода парсинга в библиотеке better-proto, вам необходимо вычитывать все данные сообщения из сокета и передавать их в метод парсинга. Если количество байт данных может изменяться, вы можете использовать специфичный для вашего протокола способ обозначения конца сообщения, например, использование специального разделителя.
Пример использования better-proto для парсинга из потока данных:
```python
from betterproto import Message
from betterproto.lib.google.protobuf.internal.decoder import _DecodeVarint
def parse_protobuf_message(socket):
# Считываем длину сообщения из потока
varint_buff = bytearray()
while True:
one_byte = socket.recv(1)
if one_byte == b'':
# Соединение закрыто
return None
varint_buff += one_byte
try:
msg_len, _ = _DecodeVarint(varint_buff, 0)
break
except IndexError:
pass
# Считываем данные сообщения из потока
msg_buff = bytearray()
while len(msg_buff) < msg_len:
one_byte = socket.recv(1)
if one_byte == b'':
# Соединение закрыто
return None
msg_buff += one_byte
# Парсим протобуф сообщение
message = Message.parse(msg_buff)
return message
```
2) Обычно протоколы, использующие protobuf, имеют описание типов сообщений и их структуру в виде `.proto` файлов. Если у вас есть доступ к этим файлам, то вы можете сгенерировать соответствующий Python-код с помощью утилиты `protoc`, которая идет в комплекте с protobuf.
Сгенерированный код содержит Python-классы для каждого описанного сообщения, и вы можете использовать эти классы для разбора протобуф сообщений, не зная их структуру заранее. Вам просто потребуется загрузить необходимый класс и вызвать метод `.parse()` или `.from_bytes()` для разбора сообщения.
Пример использования сгенерированного кода для разбора протобуф сообщений без знания их структуры:
```python
from generated_code import ExampleMessage
def parse_protobuf_message(socket):
msg_buff = bytearray()
while True:
one_byte = socket.recv(1)
if one_byte == b'':
# Соединение закрыто
return None
msg_buff += one_byte
try:
message = ExampleMessage.parse(msg_buff)
return message
except Exception:
pass
```
Здесь `ExampleMessage` - это класс, сгенерированный из соответствующего прото-файла, который описывает структуру вашего протобуф сообщения.