Sum Numbers - Client Streaming RPC
This example demonstrates client streaming RPC, where the client sends multiple requests and receives a single response after all requests are processed.
What You'll Learn
- Defining a proto service with client streaming RPC
- Implementing a client streaming handler using
ClientStream{T} - Iterating over incoming requests
- Returning a single aggregated response
Proto Definition
// sum.proto
syntax = "proto3";
package math;
service Math {
// Client streaming: stream of requests → single response
rpc Sum (stream SumRequest) returns (SumResponse);
}
message SumRequest {
double value = 1;
}
message SumResponse {
double total = 1;
int32 count = 2;
}The stream keyword before SumRequest indicates the client sends multiple messages.
Server Implementation
using gRPCServer
include("generated/math/math.jl")
using .math
# Client streaming handler
function sum_handler(ctx::ServerContext, stream::ClientStream{SumRequest})
total = 0.0
count = 0
for request in stream
if ctx.cancelled
break
end
total += request.value
count += 1
end
return SumResponse(total, count)
end
# Service definition
struct MathService end
function gRPCServer.service_descriptor(::MathService)
ServiceDescriptor(
"math.Math",
Dict(
"Sum" => MethodDescriptor(
"Sum", MethodType.CLIENT_STREAMING,
SumRequest, SumResponse,
sum_handler
)
),
nothing
)
end
function main()
server = GRPCServer("127.0.0.1", 50053;
enable_health_check = true,
enable_reflection = true
)
register!(server, MathService())
@info "gRPC server starting" port=50053
run(server)
end
main()Key Concepts
Client Streaming Handler Signature
function handler(ctx::ServerContext, stream::ClientStream{RequestType})
for request in stream
# Process each request
end
return ResponseType(...) # Single response
end- Receives
ClientStream{T}instead of a single request - Iterates over stream with
for request in stream - Returns response directly (not via stream)
Method Type
Use MethodType.CLIENT_STREAMING in the descriptor:
MethodDescriptor(
"Sum", MethodType.CLIENT_STREAMING,
SumRequest, SumResponse,
handler
)Testing
Run the Server
cd examples/03_sum_numbers
julia --project=../.. server.jlStream Numbers with grpcurl
Client streaming requires stdin piping:
echo '{"value": 1}
{"value": 2}
{"value": 3}
{"value": 4}
{"value": 5}' | grpcurl -plaintext -d @ localhost:50053 math.Math/SumExpected output:
{
"total": 15,
"count": 5
}Empty Stream
echo '' | grpcurl -plaintext -d @ localhost:50053 math.Math/SumReturns {"total": 0, "count": 0}.
Use Cases
Client streaming is ideal for:
- Batch uploads: Sending multiple records and getting a summary
- Aggregation: Computing statistics over streamed data
- File uploads: Streaming file chunks and getting confirmation
- Sensor data: Collecting measurements and returning analysis
Next Steps
Proceed to Chat to learn about bidirectional streaming, where both client and server send multiple messages.