Skip to content
Kavachकवच

gRPC: Server streaming

● Intermediate3 min

The server answers with many messages, and the client handles each as it arrives: order tracking, live prices, logs.

use std.grpc
use std.net

pub type Watch {
    id: Int
}

pub type Update {
    seq: Int
    text: String
}

fn updates(call: GrpcCall) -> GrpcReply {
    if call.method != "/shop.Orders/Watch" {
        return grpc.failed(12, "no method {call.method}")
    }
    const w = grpc.read<Watch>(call) catch _ => Watch(id: 0)
    if w.id == 0 {
        return grpc.failed(3, "not a watch")
    }
    grpc.reply_stream([
        Update(seq: 1, text: "packed"),
        Update(seq: 2, text: "shipped"),
        Update(seq: 3, text: "delivered"),
    ])
}

fn main() ! Error {
    const listener = try net.listen("127.0.0.1:0")
    const _server = spawn grpc.serve(listener, updates)
    const target = "http://{listener.address()}"
    try grpc.each<Watch, Update>(target, "/shop.Orders/Watch", Watch(id: 7), u => print("{u.seq}: {u.text}"))
    print("done")
    grpc.each<Watch, Update>(target, "/shop.Orders/Watch", Watch(id: 0), u => print("?")) catch e => print("can't: {e}")
}

The program ran and printed:

kavach run server-stream.kav

1: packed2: shipped3: delivereddonecan't: Status(code: 3, message: "not a watch")
server-stream.kav: Kavach code, then what running it prints

grpc.reply_stream sends a list as one message each; grpc.each runs its function for every message as it comes, not after the last one.