Grpc使用异常
类型有未导出的方法,并且是在不同的软件包中定义
-
导致原因:
导出的pb.go 文件中 GretterServer interface中有私有变量导致的。
// GreeterServer is the server API for Greeter service. // All implementations must embed UnimplementedGreeterServer // for forward compatibility type GreeterServer interface { SayHello(context.Context, *HelloRequest) (*HelloReply, error) mustEmbedUnimplementedGreeterServer() }
proto文件内容:
syntax = "proto3"; package helloworld; option go_package = "./helloworld"; service Greeter { rpc SayHello (HelloRequest) returns (HelloReply) {} } message HelloRequest { string name = 1; } message HelloReply { string message = 1; }
-
异常提示:
无法将 ‘&GreeterServer{}’ (类型 *GreeterServer) 用作类型 GreeterServer 类型无法实现 ‘GreeterServer’,因为类型有未导出的方法,并且是在不同的软件包中定义
-
运行异常:
.\server.go:33:35: cannot use &GreeterServer{} (value of type *GreeterServer) as type helloworld.GreeterServer in argument to pb.RegisterGreeterServer:
*GreeterServer does not implement helloworld.GreeterServer (missing mustEmbedUnimplementedGreeterServer method) -
protobuf 和 grpc 版本:
google.golang.org/grpc v1.48.0
google.golang.org/protobuf v1.28.0 -
修复方式: 增加第15行代码内容:*pb.UnimplementedXxxxxServer Xxxxx为proto文件中定义的service名称
package main import ( pb "GoRpc/proto/helloworld" "context" "flag" "google.golang.org/grpc" "net" ) var port string type GreeterServer struct { // 增加此行代码 *pb.UnimplementedGreeterServer } func init() { flag.StringVar(&port, "p", "8001", "port to connect to") flag.Parse() } func (s *GreeterServer) SayHello(ctx context.Context, r *pb.HelloRequest) (*pb.HelloReply, error) { return &pb.HelloReply{Message: "Hello.world"}, nil } func main() { server := grpc.NewServer() pb.RegisterGreeterServer(server, &GreeterServer{}) lis, _ := net.Listen("tcp", ":"+port) server.Serve(lis) }
-
修复问题的原因,查看helloworld_grpc.pb.go 文件。 实际SayHello由UnimplementedGreeterServer 结构实现
// GreeterServer is the server API for Greeter service. // All implementations must embed UnimplementedGreeterServer // for forward compatibility type GreeterServer interface { SayHello(context.Context, *HelloRequest) (*HelloReply, error) mustEmbedUnimplementedGreeterServer() } // UnimplementedGreeterServer must be embedded to have forward compatible implementations. type UnimplementedGreeterServer struct { } func (UnimplementedGreeterServer) SayHello(context.Context, *HelloRequest) (*HelloReply, error) { return nil, status.Errorf(codes.Unimplemented, "method SayHello not implemented") }