2

this my proto file:

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())
    }
}

and i got an error:

cannot use &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?

rustyx
  • 80,671
  • 25
  • 200
  • 267
Liamsuperman
  • 21
  • 1
  • 2
  • What did you use to generate the Go code from the proto file? It looks like you are using a toolkit that requires you to embed a type into your server struct. – Burak Serdar Oct 24 '21 at 21:59
  • some implementation issue. have you checkout https://buf.build/ ? it help setting up and maintaining gRPC services in Go. – twiny Oct 24 '21 at 23:06
  • @BurakSerdar that happens with the official [protoc-gen-go-grpc](https://grpc.io/docs/languages/go/quickstart/) toolkit when invoked as `protoc --go_out=. --go-grpc_out=.`. It does not happen (yet) when invoked via a plugin: `protoc --go_out=plugins=grpc:.` – rustyx Oct 25 '21 at 15:33

1 Answers1

3

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, "method SayHello not implemented")
}

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.

Brits
  • 14,829
  • 2
  • 18
  • 31