gRPC错误:缺少“未实现”的服务器方法。

huangapple go评论82阅读模式
英文:

gRPC error about missing an "Unimplemented" server method

问题

这是我的proto文件:

syntax = "proto3";
option go_package = ".;pb";

service Greeter {
  rpc SayHello (HelloRequest) returns (HelloReply); // hello
}

message HelloRequest {
  string name = 1;
}

message HelloReply {
  string message = 1;
}

这是我的代码:

package main

import (
	"awesomeProject/grpc_test/proto"
	"context"
	"google.golang.org/grpc"
	"net"
)

type Server struct {}

func (s *Server) SayHello(ctx context.Context, request *pb.HelloRequest) (*pb.HelloReply, error) {
	return &pb.HelloReply{
		Message: "hello" + request.Name,
	}, nil
}

func main() {
	g := grpc.NewServer()
	pb.RegisterGreeterServer(g, &Server{})

	lis, err := net.Listen("tcp", "0.0.0.0:8080")
	if err != nil {
		panic("failed to listen: " + err.Error())
	}

	err = g.Serve(lis)
	if err != nil {
		panic("failed to start grpc: " + err.Error())
	}
}

我遇到了一个错误:cannot use &Server{} (type *Server) as type pb.GreeterServer in argument to pb.RegisterGreeterServer:*Server does not implement pb.mustEmbedUnimplementedGreeterServer method。如何解决它?

英文:

this my proto file:

<!-- begin snippet: js hide: false console: true babel: false -->

<!-- language: lang-html -->

syntax = &quot;proto3&quot;;

option go_package = &quot;.;pb&quot;;

service Greeter {
  rpc SayHello (HelloRequest) returns (HelloReply); // hello
}

message HelloRequest {
  string name = 1;
}

message HelloReply {
  string message = 1;
}

<!-- end snippet -->

**

<!-- begin snippet: js hide: false console: true babel: false -->

<!-- language: lang-css -->

package main

import (
	&quot;awesomeProject/grpc_test/proto&quot;
	&quot;context&quot;
	&quot;google.golang.org/grpc&quot;
	&quot;net&quot;
)


type Server struct {}

func (s *Server) SayHello(ctx context.Context, request *pb.HelloRequest) (*pb.HelloReply, error) {
	return &amp;pb.HelloReply{
		Message: &quot;hello&quot; + request.Name,
	}, nil
}

func main() {
	g := grpc.NewServer()
	pb.RegisterGreeterServer(g, &amp;Server{})

	lis, err := net.Listen(&quot;tcp&quot;, &quot;0.0.0.0:8080&quot;)
	if err != nil {
		panic(&quot;failed to listen: &quot; + err.Error() )
	}

	err = g.Serve(lis)
	if err != nil {
		panic(&quot;failed to start grpc: &quot; + err.Error())
	}
}

<!-- end snippet -->

and i got an error:

cannot use &amp;Server{} (type *Server) as type pb.GreeterServer in argument to pb.RegisterGreeterServer:*Server does not implement pb.GreeterServer (missing pb.mustEmbedUnimplementedGreeterServer method)

how to solve it?

答案1

得分: 3

这在这个README中有详细说明(这个问题这个问题提供了更多的信息,也许有点多!)。

解决方法是根据错误提示编辑你的struct定义:

type Server struct {
	proto.UnimplementedGreeterServer
}

你可能还想看一下快速入门。你的服务似乎是从这个入门指南派生的,你会注意到main.go(在这里/examples/helloworld/greeter_server/main.go)包含了一个类似的struct定义。

添加proto.UnimplementedGreeterServer为所有服务提供了一个默认实现(作为生成的代码的一部分);例如:

func (UnimplementedGreeterServer) SayHello(context.Context, *HelloRequest) (*HelloReply, error) {
	return nil, status.Errorf(codes.Unimplemented, "method SayHello not implemented")
}

在结构体中包含UnimplementedGreeterServer意味着,如果你在proto文件中添加一个新的服务,然后重新编译你的应用程序,它将能够编译通过,但如果客户端尝试调用新的服务,它将返回一个未实现的错误。之前提到的问题中包含了很多关于为什么选择这种方法的讨论。

英文:

This is covered in this README (this issue and this issue provide a lot, perhaps too much!, more info).

The solution will be to edit your struct definition (as the error suggests) to:

type Server struct {
	proto.UnimplementedGreeterServer
}

You might also want to take a look at the quickstart. Your service appears to be derived from this and you will note that main.go (/examples/helloworld/greeter_server/main.go in here) includes a similar struct definition.

Adding proto.UnimplementedGreeterServer provides a default implementation for all of the services (part of the generated code); for example:

func (UnimplementedGreeterServer) SayHello(context.Context, *HelloRequest) (*HelloReply, error) {
	return nil, status.Errorf(codes.Unimplemented, &quot;method SayHello not implemented&quot;)
}

Including UnimplementedGreeterServer within the structure means that if you add a new service to the proto file and then recompile your application it will compile without error AND return an unimplemented error should a client attempt to call the new service. The issues referenced earlier include a lot of discussion around why this method was selected.

huangapple
  • 本文由 发表于 2021年10月25日 05:29:05
  • 转载请务必保留本文链接:https://go.coder-hub.com/69700899.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定