grpc go:当客户端关闭连接时,如何在服务器端知道

I am using grpc go

i have an rpc which looks roughly like this

196 service MyService {
197   // Operation 1
198   rpc Operation1(OperationRequest) returns (OperationResponse) {
199       option (google.api.http) = {
200         post: "/apiver/myser/oper1"
201         body: "*"
202     };
203   }

Client connects by using grpc.Dial() method

When a client connects, the server does some book keeping. when the client disconnects, the bookkeeping needs to be removed.

is there any callback that can be registered which can be used to know that client has closed the session.

Assuming that the server is implemented in go, there's an API on the *grpc.ClientConn that reports state changes in the connection.

func (cc *ClientConn) WaitForStateChange(ctx context.Context, sourceState connectivity.State) bool

https://godoc.org/google.golang.org/grpc#ClientConn.WaitForStateChange

These are the docs on each of the connectivity.State

https://github.com/grpc/grpc/blob/master/doc/connectivity-semantics-and-api.md

If you need to expose a channel that you can listen to for the client closing the connection then you could do something like this:

func connectionOnState(ctx context.Context, conn *grpc.ClientConn, states ...connectivity.State) <-chan struct{} {
    done := make(chan struct{})

    go func() {
        // any return from this func will close the channel
        defer close(done)

        // continue checking for state change 
        // until one of break states is found
        for { 
            change := conn.WaitForStateChange(ctx, conn.GetState())
            if !change {
                // ctx is done, return
                // something upstream is cancelling
                return
            }

            currentState := conn.GetState()

            for _, s := range states {
                if currentState == s {
                    // matches one of the states passed
                    // return, closing the done channel
                    return 
                }
            }
        }
    }()

    return done
}

If you only want to consider connections that are shutting down or shutdown, then you could call it like so:

// any receives from shutdownCh will mean the state Shutdown
shutdownCh := connectionOnState(ctx, conn, connectivity.Shutdown)