roadrunner-server/roadrunner

[๐Ÿ’ก FEATURE REQUEST]: Add support for streaming RPCs

onyn opened this issue ยท 1 comments

onyn commented

Plugin

GRPC

I have an idea!

In GRPC there are four kinds of service methods:

service HelloService {

  // Unary RPC. This is most common and familiar "request-response" scheme.
  rpc SayHello(HelloRequest) returns (HelloResponse);

  // Server streaming RPC. Client emit single request and receive sequence
  // of messages from server. This is useful for "server push" notifications.
  //
  // Example: chat service in which client subscribes to some room and
  // eventually receive chat messages from there.
  //
  // Example 2: client subscribes for market stock quotes and receives price
  // updates on interested shares.
  rpc LotsOfReplies(HelloRequest) returns (stream HelloResponse);

  // Client streaming RPC. Client send to to server sequence of messages.
  //
  // Example: client send log events which server collects in memory. Once
  // required number of messages have been collected, server flush them into
  // database using single effective bulk operation.
  rpc LotsOfGreetings(stream HelloRequest) returns (HelloResponse);
  
  // Bidirectional streaming RPC. Combination of previous two.
  rpc BidiHello(stream HelloRequest) returns (stream HelloResponse);
}

Currently roadrunner supports just unary one. If there was streams in proto definition, they turns into unary in the generated interface:

Reveal HelloServiceInterface
<?php
# Generated by the protocol buffer compiler (roadrunner-server/grpc). DO NOT EDIT!
# source: hello.proto

namespace GRPC\Hello;

use Spiral\RoadRunner\GRPC;

interface HelloServiceInterface extends GRPC\ServiceInterface
{
    // GRPC specific service name.
    public const NAME = "hello.HelloService";

    /**
    * @param GRPC\ContextInterface $ctx
    * @param HelloRequest $in
    * @return HelloResponse
    *
    * @throws GRPC\Exception\InvokeException
    */
    public function SayHello(GRPC\ContextInterface $ctx, HelloRequest $in): HelloResponse;

    /**
    * @param GRPC\ContextInterface $ctx
    * @param HelloRequest $in
    * @return HelloResponse
    *
    * @throws GRPC\Exception\InvokeException
    */
    public function LotsOfReplies(GRPC\ContextInterface $ctx, HelloRequest $in): HelloResponse;

    /**
    * @param GRPC\ContextInterface $ctx
    * @param HelloRequest $in
    * @return HelloResponse
    *
    * @throws GRPC\Exception\InvokeException
    */
    public function LotsOfGreetings(GRPC\ContextInterface $ctx, HelloRequest $in): HelloResponse;

    /**
    * @param GRPC\ContextInterface $ctx
    * @param HelloRequest $in
    * @return HelloResponse
    *
    * @throws GRPC\Exception\InvokeException
    */
    public function BidiHello(GRPC\ContextInterface $ctx, HelloRequest $in): HelloResponse;
}

Requested functionality is very similar to one offered by centrifugo.

I also found #923, but that seems about streaming large body of single request or response. Not about RPC streams.

Hey @onyn ๐Ÿ‘‹
Thanks for the feature request ๐Ÿ‘

#923 is about streaming in general. But for gRPC it is fine to have a separate ticket.