gRPC Streaming Patterns

1. Server Streaming RPC:

  • Description: In this type of RPC, the client sends a single request to the server, and the server responds with a stream of messages. The client reads from this stream of responses until there are no more messages.

  • Use Case Example: Real-time Market Data Feed.

    • Scenario: A client requests live market data (e.g., stock prices) from a server. The client sends a request for data about a specific stock, and the server streams updated stock prices as they change over time.

    • Example:

      • The client sends a request to get updates for "Stock X".

      • The server continuously sends back a stream of stock price updates for "Stock X" every time the price changes until the client decides to stop the feed.

    service StockService {
        rpc GetStockUpdates(StockRequest) returns (stream StockUpdate);
    }

    message StockRequest {
        string stockSymbol = 1;
    }

    message StockUpdate {
        string stockSymbol = 1;
        double price = 2;
        int64 timestamp = 3;
    }

2. Client Streaming RPC:

  • Description: In this type of RPC, the client sends a stream of requests to the server, and the server responds with a single response once it has received and processed all the requests.

  • Use Case Example: File Upload.

    • Scenario: A client wants to upload a large file to the server. Instead of sending the entire file in one request, it sends it in chunks (as a stream). Once the server receives all the chunks, it processes them and responds with the result (e.g., success, failure).

    • Example:

      • The client sends the file in chunks, one chunk at a time.

      • The server waits for the entire file, processes it, and returns a response (e.g., "File uploaded successfully").

    service FileUploadService {
        rpc UploadFile(stream FileChunk) returns (UploadStatus);
    }

    message FileChunk {
        bytes content = 1;
        int32 chunkNumber = 2;
    }

    message UploadStatus {
        string message = 1;
        bool success = 2;
    }

3. Bidirectional Streaming RPC:

  • Description: Both the client and the server send streams of messages to each other. The two streams operate independently, so the client and server can read and write in any order.

  • Use Case Example: Real-time Chat Application.

    • Scenario: Imagine a real-time chat application where both the client and the server need to continuously send and receive messages. The client sends messages to the server, and the server sends messages back to the client, creating a real-time, two-way conversation.

    • Example:

      • The client sends messages as they are typed, one by one.

      • The server streams messages from other participants back to the client.

      • Both streams happen simultaneously, and the server and client can send messages independently.

    service ChatService {
        rpc Chat(stream ChatMessage) returns (stream ChatMessage);
    }

    message ChatMessage {
        string username = 1;
        string message = 2;
        int64 timestamp = 3;
    }

Practical Example for Each:

  1. Server Streaming: You request the server for all your order statuses, and the server sends them one by one (think of a service that keeps sending delivery status updates as new information comes in).

  2. Client Streaming: You’re uploading multiple sensor data readings from a device to a server in batches. The server processes all the data and responds with an analysis result after the entire batch is received.

  3. Bidirectional Streaming: You’re in a video conference where both parties are sending audio and video data streams at the same time, without waiting for each other's data streams to finish.

Conclusion:

  • Server Streaming: Good for scenarios where the server needs to keep sending updates over time for a single request.

  • Client Streaming: Suitable for cases where the client has a lot of data to send but the server only needs to respond once.

  • Bidirectional Streaming: Ideal for real-time, interactive use cases where both the client and server need to continuously communicate in real-time.

Each streaming pattern has specific use cases and trade-offs in terms of latency, throughput, and complexity.