gRPC: Two-way and conversations
● Intermediate4 min
Two-way streams send many messages each way; a conversation answers each message as it arrives.
use std.grpc
use std.net
pub type Line {
text: String
}
fn echo(call: GrpcCall) -> GrpcReply {
const lines = grpc.read_all<Line>(call) catch _ => []
if lines.len() == 0 {
return grpc.failed(3, "nothing to echo")
}
grpc.reply_stream(lines.map(l => Line(text: "echo: {l.text}")))
}
fn main() ! Error {
const listener = try net.listen("127.0.0.1:0")
const _server = spawn grpc.serve(listener, echo)
const target = "http://{listener.address()}"
const lines = [Line(text: "one"), Line(text: "two"), Line(text: "three")]
try grpc.each_stream<Line, Line>(target, "/chat.Echo/Talk", lines, l => print(l.text))
print("done")
const silent: [Line] = []
grpc.each_stream<Line, Line>(target, "/chat.Echo/Talk", silent, l => print("?")) catch e => print("silent: {e}")
}The program ran and printed:
kavach run two-way.kav
echo: oneecho: twoecho: threedonesilent: Status(code: 3, message: "nothing to echo")
With each_stream, the client sends everything, then reads the answers. For a real back-and-forth, hold a conversation: each side answers the other's last message.
use std.grpc
use std.net
pub type Count {
n: Int
}
fn plus_one(call: GrpcCall) -> GrpcReply {
const c = grpc.read<Count>(call) catch _ => Count(n: 0)
if c.n == 0 {
return grpc.failed(3, "not a count")
}
print("server got {c.n}")
grpc.reply(Count(n: c.n + 1))
}
fn main() ! Error {
const listener = try net.listen("127.0.0.1:0")
const _server = spawn grpc.serve_talks(listener, plus_one, ["/game.Count/Up"])
const target = "http://{listener.address()}"
try grpc.talk_with<Count, Count>(target, "/game.Count/Up", [Count(n: 1)], c => {
print("client got {c.n}")
if c.n < 6 { [Count(n: c.n + 1)] } else { none }
})
print("done")
grpc.talk_with<Count, Count>(target, "/game.Count/Up", [Count(n: 0)], c => none) catch e => print("bad: {e}")
}The program ran and printed:
kavach run talk.kav
server got 1client got 2server got 3client got 4server got 5client got 6donebad: Status(code: 3, message: "not a count")
The client's function gives the next messages to send, or none to end its side.