1

Марку или любым, кто испытал в Protobuf-сети:частичные десериализаций с Protobuf

У меня есть архитектура, где сервер хранит пожизненные постоянные подключения к клиентам (через TCP). Поскольку уровень соединения/сервер должен иметь высокую работоспособность, он только де-сериализует сообщения и передает их на сервер/уровень приложения. Он не содержит никакой логики логики.

clients -> connection layer (deserialization) -> app layer (business logic) 

Проблема заключается в том, что в то время как я могу теперь сделать изменения в логику бизнес, я не могу изменить модель разделявшегося приложения слоя и клиентами, поскольку слой подключения зависит от модели для де-сериализации.

Есть ли способ установить уровень соединения только PARTIALLY десериализовать сообщения в базовый класс для целей пересылки/маршрутизации?

В противном случае, я думаю, мне нужно создать двоичное поле в базовом классе, которое передается как есть, и десериализуется на уровне приложения. Одноступенчатая сериализация, двухэтапная де-сериализация.

РЕДАКТИРОВАТЬ: конкретизированы

class Message 
{ 
    User user; 
    // not much else in here, potentially routing information 
} 

class RequestType1: Message 
{ 
// lots of fields 
// which are specific to this type of request/reply 
} 

class RequestType2: Message 
{ 

} 

Слой соединения не должны заботиться о структуре конкретных типов запросов. Таким образом, я могу изменить их по своему усмотрению, пока согласятся как клиентский, так и прикладной. Но в настоящее время уровень соединения выполняет десериализацию, поэтому ему нужно знать модель, и любые изменения заставляют меня перезапускать сервер соединений.

Мне просто нужно его десериализовать достаточно, чтобы маршрутизировать, что означает «пользовательская информация» + «имя/номер подтипа».

+0

Я предполагаю, что другой вариант заключается в создании слоя десериализации/маршрутизации между уровнем соединения и уровнем приложения. это отчасти вопрос дизайна, а не просто вопрос protobuf. –

+1

Можете ли вы это немного рассказать, I.e.пример полного сообщения (малый, желательно), а также информацию о том, какие поля и т. д. вы хотите для частичной десериализации? Кроме того, если вы * сделаете * частично deserialize, то, что вы будете передавать вниз по течению - оригинальное полное сообщение? И т.д. Рад помочь, но нужно больше контекста. –

+0

Посмотрите сейчас, возможно, это имеет смысл. –

ответ

2

Прежде всего: вы не должны отправлять серийные сообщения protobuf непосредственно через провод, поскольку TCP основан на потоке. Вы никогда не узнаете, когда получили полное сообщение.

WithLengthPrefix используется только для этого. Префикс для всех сообщений с двоичной длиной, чтобы вы могли узнать, когда поступило полное сообщение.

Если бы я был вами, я бы создал заголовок, который содержит достаточно информации для маршрутизации. Длина обязательна, но вы также можете указать тип транспортируемого сообщения и т. Д. Это означает, что вам нужно только проверять заголовок для каждого сообщения, а не ссылаться на дорогостоящую десериализацию.

запрос

Пример заголовка:

  • версия заголовка (byte)
  • тип контента (byte) (вам нужно создать отображение где-то)
  • длина содержимого (int)

В настоящее время я пишу небольшой аддон для моего Griffin.Networking (http://github.com/jgauffin/griffin.networking), который будет иметь небольшой заголовок и использовать protobuf для сообщений. Наблюдайте за проектом, чтобы получить обновление, когда оно было совершено.

+0

Да, у меня уже был префикс размера и теперь добавлен заголовок маршрутизации. Примите ваш ответ, поскольку Марк не опубликовал его, и вы потратили некоторое время на его запись. Приветствия. –

+0

Это позор, если это все еще актуально. С сильно определенными контрактами данных возможно иметь сериализацию потоковой передачи и длину неизвестного сообщения. Я достиг этого с JSON, и в настоящее время я перехожу к BinaryWriter с той же функцией. Преимущество, очевидно, является более низким пиковым потреблением памяти, а также более короткие времена выполнения, связанные с ожиданием создания сообщения. Проблема с таким интерфейсом, однако, заключается в том, что десериализованный поток потребляется в правильном порядке, если имеется несколько перечислимых разделов. (Реализовано в C# с IEnumerable <> и yield) – Todd

Смежные вопросы