Как данные отправляются с клиента на (мультисервисный) сервер в gRPC

#web-services #protocol-buffers #grpc #protobuf-c

#веб-сервисы #буферы протокола #grpc #протобуф-c #protobuf-c

Вопрос:

Я использую клиент-серверную платформу gRPC в одном из своих приложений (распознавание речи). Есть несколько важных вещей, которые я хочу прояснить своими наблюдениями.

1. Как отправляется необязательное поле данных, когда оно не заполнено клиентом?

Давайте посмотрим на следующий пример: (предположим, что используется proto3, поэтому все поля по умолчанию являются необязательными)

 service NameStudent {
    rpc GetRoll(Student) returns (Details) {}
}

#Student'd details
message Student{
    int32 roll = 1;
    string name = 2;
    string gender = 4;
    int32 age = 3;
    DOB dateofbirth = 5;
}

#Students Date of Birth
message DOB {
    int32 dd = 1;
    int32 mm = 2;
    int32 yy = 3;
}

#Parent's details
message Parent{
    string parent =1;
}

#Students all details (includes student   parent)
message Details {
    Student student = 1;
    Parent parent = 4;
}
  

Предположим, что служба принимает (входные данные от клиента) некоторые из сведений об ученике, например, список, имя и возраст, и возвращает (все) сведения об этом ученике

итак, теперь, если вместо отправки всех трех сведений (т. Е. списка, имени и возраста), также могут быть отправлены даже любые одна или две данные и (логически предположить, что) служба работает.

В таких случаях сервер получит все поля (с пробелами / нулями для пропущенных полей) или клиент вообще не отправит эту пропущенную информацию? (смотрите ниже представления двоичных данных, отправляемых с клиента)

 // roll and name filled
// age is left blank
// gender and DOB are always sent blank from client
{
    roll: 170012,
    name: "John Doe",
    age: ,
    gender: "",
    dateofbirth: {
           dd: ,
           mm: ,
           yy: 
    }
}
  

или

 //only roll and name is sent and rest is just not sent
{
    roll: 170012,
    name: "John Doe"
}
  

2. Возможно ли подключить одну заглушку для двух сервисов?

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

Ответ №1:

Вопрос 1

Взгляните на эту документацию protobuf. В частности:

Для любых неповторяющихся полей в proto3 или необязательных полей в proto2 закодированное сообщение может иметь или не иметь пару ключ-значение с этим номером поля.

Однако на практике я заметил, что необязательные поля со значениями по умолчанию опущены при сериализации. Когда protobuf десериализуется, анализатор интерпретирует отсутствующее поле как значение по умолчанию. Вы можете наблюдать это поведение самостоятельно, используя SerializeToString() метод для объектов Python protobuf.

Вопрос 2

Абсолютно возможно подключить несколько служб gRPC к одному серверу и взаимодействовать с несколькими службами по одному каналу на стороне клиента. gRPC использует пути HTTP2 для различения нескольких служб, подключенных к одному серверу. Взгляните на этот сгенерированный gRPC Python код для примера этого. add_GreeterServicer_to_server связывает пользовательский обработчик с путем /helloworld.Greeter/SayHello , который заглушка затем использует для идентификации этой службы на сервере.

Комментарии:

1. Привет, @ Richard, красиво составленный ответ (голосую за это). Я получил ответ на вопросы , но будет полезно понять пример, которым вы поделились в ответе 2 . Я не разбираюсь в python , поэтому я сделаю все возможное, чтобы пройти этот пример шаг за шагом. Между тем, если вы можете / хотите добавить больше объяснений по этому поводу, пожалуйста, сделайте это… Еще раз спасибо