Protobuf Grpc使用异常 类型有未导出的方法,并且是在不同的软件包中定义

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")
    }
    
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值