I am building an API using gRPC and in server side, I want to receive a notification when a client disconnects, identify it and perform some tasks based on that.
So far, I was able to detect client disconnection using grpc.StatsHandler
method HandleConn
. I tried passing values using context, but they can't be accessed from server side.
Client side:
conn, err := grpc.DialContext(
context.WithValue(context.Background(), "user_id", 1234),
address,
grpc.WithInsecure(),
)
Server side:
// Build stats handler
type serverStats struct {}
func (h *serverStats) TagRPC(ctx context.Context, info *stats.RPCTagInfo) context.Context {
return ctx
}
func (h *serverStats) HandleRPC(ctx context.Context, s stats.RPCStats) {}
func (h *serverStats) TagConn(ctx context.Context, info *stats.ConnTagInfo) context.Context {
return context.TODO()
}
func (h *serverStats) HandleConn(ctx context.Context, s stats.ConnStats) {
fmt.Println(ctx.Value("user_id")) // Returns nil, can't access the value
switch s.(type) {
case *stats.ConnEnd:
fmt.Println("client disconnected")
break
}
}
// Build server
s := grpc.NewServer(grpc.StatsHandler(&serverStats{}))
I want to access the value passed from client side in server side. What is the right way to do it, or is there any other way to identify the client that has disconnected?
I tried passing values using context
I'm not sure of the specifics but this might if you use GRPC metadata: (github.com/grpc/grpc-go/blob/master/Documentation/…), but i'm not sure the sequence of GRPC method invocations and the specifics of when/how/where metadata is sent in nGRPC protocol (ie will it always be availble inHandleConn
??? What's your use case for this? There might be alternatives to handling disconnect by making operations idempotent (or potentially other approaches). – dm03514