gRPC: как вызвать удаленную процедуру с комбинацией статических и потоковых параметров? - PullRequest
1 голос
/ 07 ноября 2019

Я пытаюсь передать файл с помощью gRPC. Я могу отправлять данные, разбитые на куски, используя поток gRPC. Я ищу способ также передать имя файла с данными. Я уверен, что есть очевидное решение, которое я скучаю. Но вот несколько подходов, о которых я могу подумать:

  1. Отправка имени файла с каждым чанком, что является очевидным недостатком повторной передачи одних и тех же данных. Файл .proto будет выглядеть как
service KeyValueStore {
    rpc upload (stream FileData) returns (UploadStatus) {}
}

message FileData {
    string filename = 1;
    bytes data = 2;
}
Отправка имени файла в качестве первого чанка. Приемник должен знать о таком кодировании.

Но я ищу нехакерское решение.

Я надеялся найти решение, подобное

service KeyValueStore {
    rpc upload (FileName, stream FileData) returns (UploadStatus) {}
}

Но это невозможно и также не рекомендуется в соответствии с ответом здесь

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

1 Ответ

0 голосов
/ 13 ноября 2019

Пост, который вы указали, верный. В качестве входных данных вы будете использовать один буфер протокола и, как правило, он должен называться как «FooRequest». То же самое относится и к объекту ответа, который должен называться что-то вроде «FooResponse». Отделение объектов запроса и ответа от их содержимого даст вам возможность со временем изменить свой API обратно-совместимым образом.

Тот факт, что мы не поддерживаем несколько типов запросов, на практике не является препятствием,потому что протос может быть вложен произвольно. Рассмотрим такой API.

message FileData {
    string filename = 1;
    bytes data = 2;
}

message UploadRequest {
    oneof payload {
        string filename = 1;
        FileData file_data = 2;
    }
}

service KeyValueStore {
    rpc upload (stream UploadRequest) returns (UploadResponse) {}
}

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

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

Ваше решение по этим пунктам будет частью вашего API, но not будет автоматически реализован protobuf как IDL. Вам нужно явно обработать эти угловые случаи в коде вашего сервера. Помните, однако, что, поскольку это соображения API, они должны записываться где-то в вашем файле protobuf. Сделайте все возможное, чтобы каждое сообщение, RPC и поле имели четкую и краткую строку документации.

...