Можно ли выполнять запросы RPC от сервера к клиенту с помощью gRPC? - PullRequest
0 голосов
/ 01 ноября 2018

Предисловие:

Я не использовал gRPC раньше. Я только делаю первый взгляд на эту технологию и пытаюсь понять, могу ли я использовать ее в своем проекте или нет. Я использую C # с чистым ядром 2.1, если это что-то имеет значение.

Вопрос:

У меня есть один сервер и несколько клиентов, и мне нужно делать запросы RPC от сервера к клиентам. Это доступно с gRPC? И если да, то как я могу это сделать?

Ответы [ 3 ]

0 голосов
/ 08 ноября 2018

С помощью gRPC сервер не может инициировать контакт с клиентом. Тем не менее, клиент может отправить начальный rpc на сервер и затем ждать своего ответа, пока сервер не получит требуемый ресурс следующим образом:

using (var call = client.InitialContact(clientID))
{
    var responseStream = call.ResponseStream;
    while (await responseStream.MoveNext()){
        //do something if there is a response
    }
}
0 голосов
/ 12 ноября 2018

Ответ от https://groups.google.com/forum/#!topic/grpc-io/wAF9T0nQcH0

Автор ответа: Джош Хамфрис (Джош, если вы прочтете эту тему, пожалуйста, опубликуйте ваш ответ здесь, и я приму его и удалю свою копию)

Вы можете использовать двунаправленный поток, где каждое сообщение, которое сервер отправляет в потоке, будет содержать одно сообщение от клиента в ответ. Фактические типы запросов и ответов могут иметь одно из: в ответном сообщении есть опция в одном для каждой фактической операции RPC (и ее типа запроса); сообщение запроса (отправленное клиентом) фактически определяет типы ответов. Пример такого можно увидеть в сервисе отражения сервера. Тем не менее, это обычный RPC клиент-сервер. Вы бы просто поменялись типами запросов и ответов (и чтобы сервер был тем, который инициирует запросы, сначала отправив сообщение «ответ» и получив в ответ «запрос»).

Для постепенного удаления сервер просто должен прекратить использовать поток для отправки запросов, дождаться ответов на все невыполненные операции, а затем закрыть поток / завершить RPC. Когда клиент завершает работу, он может прекратить прием сообщений от сервера (после каждого полученного сообщения сразу же отправьте сообщение об ошибке по линии «завершение работы»).

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

В сторону: я работал над чем-то, что вы можете найти полезным - общим механизмом туннелирования gRPC. Туннель настраивается через службу gRPC, которая предоставляет те же функциональные возможности, что и транспорт низкого уровня gRPC. Есть несколько интересных вариантов использования, но сервер-клиент является наиболее интересным IMO. Если вам интересно, вы можете покопаться в незавершенной работе: https://github.com/jhump/grpctunnel. (К сожалению, я не знаю, когда мне удастся действительно закончить эту библиотеку, но она может иметь некоторые интересные идеи / код, который вы могли бы использовать.)

0 голосов
/ 07 ноября 2018

Запросы, инициируемые сервером, не являются первоклассной функцией gRPC, однако, этот вид топографии PRC всегда возможен с семантикой потоковой передачи.

Например, поток будет:
1) все клиенты устанавливают долгоживущие потоковые RPC с сервером
2) сервер теперь может отправлять сообщения каждому клиенту в этих потоках, как если бы каждое сообщение было отдельным RPC

...