Search code examples
goprotocol-buffersgrpc

Failed to get RPC descriptor


I have the following proto files:

service_myservice.proto

service MyService {
    rpc GetData(GetRequest) returns (GetResponse) {}
}

server.go

type Server struct {
    pb.UnimplementedMyServiceServer
    config util.Config
}

// NewServer creates a new gRPC server.
func NewServer(config util.Config) (*Server, error) {
    server := &Server{
        config: config,
    }

    return server, nil
}

and then in main package I am calling this function

func runGrpcServer(config util.Config) {
    server, err := gapi.NewServer(config)
    if err != nil {
        log.Fatal().Err(err).Msg("cannot create server")
    }

    grpcLogger := grpc.UnaryInterceptor(gapi.GrpcLogger)
    grpcServer := grpc.NewServer(grpcLogger)
    pb.RegisterMyServiceServer(grpcServer, server)
    reflection.Register(grpcServer)

    listener, err := net.Listen("tcp", config.GRPCServerAddress)
    if err != nil {
        log.Fatal().Err(err).Msg("cannot create listener")
    }

    log.Info().Msgf("start gRPC server at %s", listener.Addr().String())
    err = grpcServer.Serve(listener)
    if err != nil {
        log.Fatal().Err(err).Msg("cannot start gRPC server")
    }
}

I am using evans (https://github.com/ktr0731/evans) to test my grpc calls. My gRPC server is running and I can connect to the localhost on the specific port (9090) with evans.

However, when I call show service in evans I get following response:

localhost:9090> show service
+---------+-----+--------------+---------------+
| SERVICE | RPC | REQUEST TYPE | RESPONSE TYPE |
+---------+-----+--------------+---------------+
+---------+-----+--------------+---------------+
localhost:9090> call GetData
command call: failed to get the RPC descriptor for: GetData: service unselected

I thought that if I add pb.UnimplementedMyServiceServer in my Server struct, that this is forward compatible. But apparently, I am missing some piece of code.

What part is missing, for the MyService to be forward compatible?


Solution

  • When evans is used in the REPL mode, you should select a package before calling show service and select a service before calling call GetData.

    localhost:9090> show package
    +-------------------------+
    |         PACKAGE         |
    +-------------------------+
    | example                 |
    | grpc.reflection.v1      |
    | grpc.reflection.v1alpha |
    +-------------------------+
    
    localhost:9090> package example
    
    example@localhost:9090> show service
    +-----------+---------+--------------+---------------+
    |  SERVICE  |   RPC   | REQUEST TYPE | RESPONSE TYPE |
    +-----------+---------+--------------+---------------+
    | MyService | GetData | GetRequest   | GetResponse   |
    +-----------+---------+--------------+---------------+
    
    example@localhost:9090> service MyService
    
    example.MyService@localhost:9090> call GetData
    id (TYPE_INT32) => 1