Streaming
View SourcegRPC has four call types. This guide shows each one on the server and the client. Messages are maps throughout.
Unary
One request, one reply. The handler returns {ok, Reply} or an error.
say_hello(#{name := Name}, _Ctx) ->
{ok, #{message => <<"hello ", Name/binary>>}}.{ok, Reply} = livery_grpc_client:call(Conn, Method, #{name => <<"ada">>}).Server-streaming
One request, a stream of replies. The handler gets a Send function and
returns ok when done.
say_hello_stream(#{name := Name}, Send, _Ctx) ->
[Send(#{message => <<"hi ", Name/binary, $\s, (integer_to_binary(I))/binary>>})
|| I <- lists:seq(1, 3)],
ok.The client collects the replies into a list:
{ok, Replies} = livery_grpc_client:call(Conn, Method, #{name => <<"ada">>}).Client-streaming
A stream of requests, one reply. The handler reads the requests through a stream handle and returns a single reply.
collect(Stream, _Ctx) ->
{ok, Requests, _Stream} = livery_grpc_stream:recv_all(Stream),
{ok, summarize(Requests)}.The client sends a list and gets one reply:
{ok, Reply} = livery_grpc_client:client_stream(Conn, Method, [Req1, Req2, Req3]).For finer control (send as you go), use open/2 then send/2 and
send_end/1.
Bidirectional
Both sides stream, independently. The handler reads with recv/1 and
replies with send/2, interleaved, and returns ok when the client is
done.
chat(Stream, _Ctx) ->
loop(Stream).
loop(Stream) ->
case livery_grpc_stream:recv(Stream) of
{ok, Msg, Stream1} ->
livery_grpc_stream:send(Stream1, reply_for(Msg)),
loop(Stream1);
{eof, _Stream1} ->
ok
end.The client opens a call and drives it:
{ok, Call} = livery_grpc_client:open(Conn, Method),
ok = livery_grpc_client:send(Call, #{...}),
{ok, Reply, Call1} = livery_grpc_client:recv(Call),
ok = livery_grpc_client:send_end(Call1). %% half-close when done sendingrecv/1 returns {ok, Reply, Call} per message, {eof, Outcome, Call}
when the server finishes (carrying the final status), or
{error, Reason, Call}.
Notes
- Reading and writing happen in the one handler process, so a
bidirectional handler can interleave
recv/1andsend/2freely. - gRPC-Web supports unary and server-streaming only; client-streaming and bidirectional need gRPC over HTTP/2. See gRPC-Web.
- For backpressure on large streams, see flow control.