Golang gRPC HelloWorld示例扩展修改后出现undefined: helloworld.TheGRPCNotificationMessage错误求助
我来帮你梳理下问题,这几个小改动确实容易踩坑,咱们一步步来:
1. 先修复Proto文件的错误定义
你proto文件最后那段Empty { ... }是完全错误的——你已经import了google/protobuf/empty.proto,直接用google.protobuf.Empty作为返回类型就好,不需要自己重复定义。删掉这段错误代码,否则protoc编译会出问题,生成的Go文件也会有异常。
修正后的proto文件末尾应该去掉那个无效的Empty块,保持原样。
2. 服务端要和你定义的gRPC服务匹配
你的proto里定义的服务是TheGRPCNotificationService,但服务端代码还在沿用官方HelloWorld示例里的Greeter服务相关代码:
- 结构体嵌入的是
pb.UnimplementedGreeterServer,应该换成pb.UnimplementedTheGRPCNotificationServiceServer - 注册服务用的是
pb.RegisterGreeterServer(s, &server{}),必须改成pb.RegisterTheGRPCNotificationServiceServer(s, &server{})
3. 方法签名不匹配+字段名错误
你的ReceiveNotificationWithGRPC方法有两个明显问题:
- 你在proto里定义这个RPC是流式输入(
stream TheGRPCNotificationMessage),所以方法签名完全不对,正确的签名应该是:
func (s *server) ReceiveNotificationWithGRPC(stream pb.TheGRPCNotificationService_ReceiveNotificationWithGRPCServer) error { // 循环读取流式消息 for { in, err := stream.Recv() if err == io.EOF { // 客户端结束流,返回空响应 return stream.SendAndClose(&emptypb.Empty{}) } if err != nil { return err } log.Printf("Received streaming notification: %v", in.Message) } }
- 你的消息字段是
message,不是HelloWorld里的Name,所以要把in.Name改成in.Message
另外,你还需要实现SendNotificationWithGRPC方法(符合proto定义),示例代码:
func (s *server) SendNotificationWithGRPC(ctx context.Context, in *pb.TheGRPCNotificationMessage) (*emptypb.Empty, error) { log.Printf("Received single notification: %v", in.Message) return &emptypb.Empty{}, nil }
别忘了在服务端导入google.golang.org/protobuf/types/known/emptypb包。
4. 客户端也要修正服务客户端实例
客户端里你创建的是pb.NewGreeterClient(conn),这是HelloWorld的客户端,应该换成pb.NewTheGRPCNotificationServiceClient(conn),否则调用SendNotificationWithGRPC会找不到对应方法。
最后一步:重新编译Proto
修正完proto文件后,重新执行你之前的protoc编译命令,确保生成的GRPCNotification.pb.go和GRPCNotification_grpc.pb.go是最新的,然后再启动服务端和客户端试试。
内容的提问来源于stack exchange,提问作者user15148251

