Skip to content
Kavachकवच

gRPC: Client streaming

● Intermediate3 min

The client sends many messages on one call, and the server answers once: uploads, batches, totals.

use std.grpc
use std.net

pub type Item {
    qty: Int
}

pub type Total {
    count: Int
    sum: Int
}

fn add_up(call: GrpcCall) -> GrpcReply {
    const items = grpc.read_all<Item>(call) catch _ => []
    if items.len() == 0 {
        return grpc.failed(3, "no items")
    }
    const first = grpc.read<Item>(call) catch _ => Item(qty: 0)
    print("first: {first.qty}")
    let sum = 0
    for i in items {
        sum += i.qty
    }
    grpc.reply(Total(count: items.len(), sum: sum))
}

fn main() ! Error {
    const listener = try net.listen("127.0.0.1:0")
    const _server = spawn grpc.serve(listener, add_up)
    const target = "http://{listener.address()}"
    const total = try grpc.call_stream<Item, Total>(target, "/shop.Cart/AddUp", [Item(qty: 5), Item(qty: 6), Item(qty: 7)])
    print("{total.count} items, {total.sum} in all")
    const empty: [Item] = []
    const nothing = grpc.call_stream<Item, Total>(target, "/shop.Cart/AddUp", empty) catch e => {
        print("empty: {e}")
        return
    }
    print(nothing.count)
}

The program ran and printed:

kavach run client-stream.kav

first: 53 items, 18 in allempty: Status(code: 3, message: "no items")
client-stream.kav: Kavach code, then what running it prints

grpc.read_all gives every message the client sent, in order. A handler written for one message still works: grpc.read gives the first.