Независимый от платформы протокол сокета protobuf - какое сообщение я получу? - PullRequest
4 голосов
/ 04 ноября 2010

Я готовлюсь написать независимый от платформы протокол сокетов.После некоторого первоначального исследования протобуф кажется правильным.Я новичок в protobuf и не могу понять одну конкретную проблему.

Мои требования:

  • Абсолютно независимый от платформы клиент;

  • C # сервер;

  • Асинхронная передача сообщений;

  • Работа из файла .proto (поэтому нет вывода изсуществующие классы);

  • Должен иметь возможность отправлять сообщения без предварительного уведомления сервера / клиента о типе сообщения.

У меня естьуже нашли (De)SerializeWithLengthPrefix методы, и они являются началом. Что я не могу понять, так это как получить сообщение, если я заранее не знаю тип.

Я уже видел, что protobuf-net поддерживает наследование и может определять типсообщения, поэтому для protobuf-net будет работать наследование всех сообщений от общего базового типа. Однако, это не зависит от платформы, и я ищу независимый от платформы способ сделать это.

Поэтому мой вопрос: как я могу отправлять свои сообщения так, чтобы любой клиентМожно ли десериализовать их, не зная заранее типа?

1 Ответ

2 голосов
/ 04 ноября 2010

Если требуется работа с несколькими сообщениями разных типов:

Просто свяжите уникальный номер с каждым другим типом сообщения и используйте в качестве префикса к сообщению; Вы можете сделать это тривиально с необязательным целочисленным параметром для перегруженного метода SerializeWithLengthPrefix. Клиенту придется предварительно обработать этот префикс (или он может быть обработан в protobuf-net с помощью Serializer.NonGeneric, который имеет метод десериализации, обеспечивающий обратный вызов для получения типа из этого номера префикса).


Если требуется работать с полностью неизвестными данными :

Учитывая ваши требования, я подозреваю порт Джона будет более подходящим; поскольку вы делаете упор на независимость от платформы и .proto, а не на умозаключение (в котором превосходит protobuf-net) или другие специальные расширения / утилиты .NET.

Обратите внимание, что хотя .proto можно скомпилировать (через protoc) в обычный поток protobuf, работа с полностью посторонними данными в приемнике ... нерегулярна. Вероятно, это можно сделать, рассматривая все как расширения или работая с кодированными потоками, но ...


Редактировать следующее обсуждение в комментариях:

Простая схема здесь может быть просто:

message BaseMessage {
    optional SomeMessage someMessage = 1;
    optional SomeOtherMessage someOtherMessage = 2;
    optional SomeThirdMessage someThirdMessage = 3;
}
message SomeMessage {...}
message SomeOtherMessage {...}
message SomeThirdMessage {...}

(вы можете добавить дискриминатор, если это поможет)

Это на самом деле по существу , как protobuf-net обрабатывает наследование , но легко представляется другими клиентами и автоматически обрабатывает все, например, длину вложенных сообщений.

...