使用UnimplementedServer和其他嵌入接口的Grpc Golang

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

Grpc Golang using UnimplementedServer with other embedded interfaces

问题

我最近更新了最新的protoc和带有现有proto 3代码库的Go插件,并且在新的UnimplementedServer功能上遇到了问题。用于Grpc服务器的结构体已经嵌入了描述此服务实现的方法的另一个接口。在我的结构体中嵌入UnimplementedServer引用后,编译器会给出一个模棱两可的错误,并告诉我不再实现我的服务方法。我在代码结构上是否存在问题?以下是可复现问题的代码,使用的是libprotoc 3.17.3、protoc-gen-go v1.27.1和protoc-gen-go-grpc 1.1.0:

api/proto/core_service.proto:


package testbed;

option go_package = "internal/proto";

service Core {
	rpc CreateThing(Thing) returns (ThingResponse) {};
}

message Thing {
	string name = 1;
}

message ThingResponse {
	int64 result = 1;
}

internal/core.go:


import (
	"context"

	"testbed.org/demo/internal/proto"
)

type CoreApi interface {
	CreateThing(ctx context.Context, t *proto.Thing) (*proto.ThingResponse, error)
}

internal/core_endpoints.go:


import (
	"context"

	"testbed.org/demo/internal/proto"
)

type CoreEndpoints struct {}

func (ce CoreEndpoints) CreateThing(_ context.Context, _ *proto.Thing) (*proto.ThingResponse, error) {
	return nil, nil
}

cmd/service.go:


import (
	//"context"
	. "testbed.org/demo/internal"
	"testbed.org/demo/internal/proto"
	"google.golang.org/grpc"
)

type MyServer struct {
	CoreApi
	proto.UnimplementedCoreServer
}

func main() {
	mySvr := &MyServer{CoreApi: &CoreEndpoints{}}
	//_, _ = mySvr.CoreApi.CreateThing(context.Background(), &proto.Thing{})
	grpcSvr := grpc.NewServer()
	proto.RegisterCoreServer(grpcSvr, mySvr)
}

Build:

protoc -I api/proto/ api/proto/*.proto --go_out=. --go-grpc_out=.
go build -o bin/svc cmd/service.go
cmd/service.go:19:26: MyServer.CreateThing is ambiguous
cmd/service.go:19:26: cannot use mySvr (type *MyServer) as type "testbed.org/demo/internal/proto".CoreServer in argument to "testbed.org/demo/internal/proto".RegisterCoreServer:
	*MyServer does not implement "testbed.org/demo/internal/proto".CoreServer (missing CreateThing method)
gmake: *** [Makefile:8: service] Error 2
英文:

I've recently updated to the latest protoc and Go plugins with an existing proto 3 codebase, and am running into trouble with the new UnimplementedServer functionality. The struct that is used for the Grpc server already embeds another interface describing the methods implemented by this service. After embedding the UnimplementedServer reference in my struct, I get an ambiguous error from the compiler and it tells me I am not implementing my service method anymore. Is there some issue with the way I have structured the code? Code to reproduce follows, with libprotoc 3.17.3, protoc-gen-go v1.27.1, and protoc-gen-go-grpc 1.1.0:
api/proto/core_service.proto:


package testbed;

option go_package = "internal/proto";

service Core {
	rpc CreateThing(Thing) returns (ThingResponse) {};
}

message Thing {
	string name = 1;
}

message ThingResponse {
	int64 result = 1;
}

internal/core.go:


import (
	"context"

	"testbed.org/demo/internal/proto"
)

type CoreApi interface {
	CreateThing(ctx context.Context, t *proto.Thing) (*proto.ThingResponse, error)
}

internal/core_endpoints.go:


import (
	"context"

	"testbed.org/demo/internal/proto"
)

type CoreEndpoints struct {}

func (ce CoreEndpoints) CreateThing(_ context.Context, _ *proto.Thing) (*proto.ThingResponse, error) {
	return nil, nil
}

cmd/service.go:


import (
	//"context"
	. "testbed.org/demo/internal"
	"testbed.org/demo/internal/proto"
	"google.golang.org/grpc"
)

type MyServer struct {
	CoreApi
	proto.UnimplementedCoreServer
}

func main() {
	mySvr := &MyServer{CoreApi: &CoreEndpoints{}}
	//_, _ = mySvr.CoreApi.CreateThing(context.Background(), &proto.Thing{})
	grpcSvr := grpc.NewServer()
	proto.RegisterCoreServer(grpcSvr, mySvr)
}

Build:

protoc -I api/proto/ api/proto/*.proto --go_out=. --go-grpc_out=.
go build -o bin/svc cmd/service.go
cmd/service.go:19:26: MyServer.CreateThing is ambiguous
cmd/service.go:19:26: cannot use mySvr (type *MyServer) as type "testbed.org/demo/internal/proto".CoreServer in argument to "testbed.org/demo/internal/proto".RegisterCoreServer:
	*MyServer does not implement "testbed.org/demo/internal/proto".CoreServer (missing CreateThing method)
gmake: *** [Makefile:8: service] Error 2

答案1

得分: 1

根据日志显示,'MyServer'没有实现'CoreServer'接口。

type MyServer struct {
    endpoint CoreEndpoints
    proto.UnimplementedCoreServer
}

func (srv MyServer) CreateThing(ctx context.Context, in *proto.Thing) (*proto.ThingResponse, error) {
    return srv.endpoint.CreateThing(ctx, in)
}
英文:

As the log says, 'Myserver' does not implement the coreserver interface.

type MyServer struct {
    endpoint CoreEndpoints
    proto.UnimplementedCoreServer
}

func (srv MyServer) CreateThing(ctx context.Context, in *proto.Thing)(*proto.ThingResponse, error) {
    return srv.endpoint.CreateThing(ctx,in)
}

huangapple
  • 本文由 发表于 2021年8月10日 08:35:57
  • 转载请务必保留本文链接:https://go.coder-hub.com/68719920.html
匿名

发表评论

匿名网友

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

确定