Двунаправленный поток¶
Каждый из участников взаимодействия отправляет свои сообщения в потоковом режиме, это может происходить параллельно, что означает, что порядок, в котором отправляются сообщения от клиента и от сервера, отсутствует. Клиент инициирует удалённый вызов процедуры с помощью указания имени метода и метаданных. Затем сервер может немедленно ответить возвратом статуса и метаданных (или же может это сделать, когда клиент отправит все свои сообщения).
Диаграмма¶
sequenceDiagram
participant C as gRPC Client
participant S as gRPC Server
C->>S: Имя метода + метаданные
S->>C: Сообщение ответа 1
C->>S: Сообщение запроса 1
S->>C: Сообщение ответа 2
S->>C: Сообщение ответа 3
S->>C: Сообщение ответа (response message) + gRPC-статус + метаданные
Protobuf¶
Реализация на сервере¶
Приведём пример, в котором сперва читаются все сообщения клиентского потока, а затем отправляются сообщения серверного потока. Однако, легко придумать пример, когда сообщения потока отправляются асинхронно или в ответ н какое-либо сообщение с клиента.
public override async Task DuplexStreamingFunction(
IAsyncStreamReader<InputMessage> requestStream,
IServerStreamWriter<OutputMessage> responseStream,
ServerCallContext context)
{
// итерируемся по клиентским сообщениям
await foreach (var createRequest in requestStream.ReadAllAsync())
{
// реализация обработки
}
// итерируемся по IEnumerable<OutputMessage> или IAsyncEnumerable<OutputMessage>
foreach (var outputMessage in outputMessageEnumerable)
{
await responseStream.WriteAsync(outputMessage);
}
}
Использование на клиенте¶
Также приведём пример, в котором сперва отправляем все клиентские сообщения, а затем получаем все серверные сообщения.
using var duplexStreamingCall = client.DuplexStreamingFunction();
// итерируемся по IEnumerable<InputMessage> или IAsyncEnumerable<InputMessage>
foreach (var inputMessage in inputMessageEnumerable)
{
await duplexStreamingCall.RequestStream.WriteAsync(request);
}
// Сообщаем серверу о завершении передачи
await duplexStreamingCall.RequestStream.CompleteAsync();
// Читаем поток с сервера
await foreach (var OutputMessage in duplexStreamingCall.ResponseStream.ReadAllAsync())
{
// обработка переданных сообщений
}
Ссылки¶
Диаграммы всех видов взаимодействия
примеры Protobuf
Примеры реализаций на сервере
Пример клиента
Дата создания : 23 апреля 2023 г.