我是golang的新手,想要尝试使用grpc代码来更好地理解它。为了做到这一点,我按照这里显示的例子:
https://devicharan.wordpress.com/
源代码在这里: https://github.com/devicharan/basicwebapp
不幸的是,当我运行此代码并进行构建时,我收到以下错误消息:
# basicwebapp/proto
proto/CatalogService.pb.go:126: cannot use _CatalogService_GetProductCatalog_Handler (type func(interface {}, context.Context, []byte) (proto.Message, error)) as type grpc.methodHandler in field value
proto/RecommendationService.pb.go:99: cannot use _RecommendationService_GetRecommendations_Handler (type func(interface {}, context.Context, []byte) (proto.Message, error)) as type grpc.methodHandler in field value
我不知道这意味着什么或我需要改变什么才能开始寻找解决方案。这是代码本身还是Go配置的问题?另外,有人可以推荐一个很好的Go调试器吗?
以下是CatalogService.pb.go的代码:
// Code generated by protoc-gen-go.
// source: CatalogService.proto
// DO NOT EDIT!
/*
Package protos is a generated protocol buffer package.
It is generated from these files:
CatalogService.proto
Product.proto
RecommendationService.proto
It has these top-level messages:
Category
CatalogResponse
CatalogRequest
*/
package protos
import proto "github.com/golang/protobuf/proto"
import (
context "golang.org/x/net/context"
grpc "google.golang.org/grpc"
)
// Reference imports to suppress errors if they are not otherwise used.
var _ context.Context
var _ grpc.ClientConn
// Reference imports to suppress errors if they are not otherwise used.
var _ = proto.Marshal
type Category struct {
CategoryName string `protobuf:"bytes,1,opt,name=categoryName" json:"categoryName,omitempty"`
}
func (m *Category) Reset() { *m = Category{} }
func (m *Category) String() string { return proto.CompactTextString(m) }
func (*Category) ProtoMessage() {}
type CatalogResponse struct {
Products []*Product `protobuf:"bytes,1,rep,name=products" json:"products,omitempty"`
}
func (m *CatalogResponse) Reset() { *m = CatalogResponse{} }
func (m *CatalogResponse) String() string { return proto.CompactTextString(m) }
func (*CatalogResponse) ProtoMessage() {}
func (m *CatalogResponse) GetProducts() []*Product {
if m != nil {
return m.Products
}
return nil
}
type CatalogRequest struct {
Category *Category `protobuf:"bytes,1,opt,name=category" json:"category,omitempty"`
}
func (m *CatalogRequest) Reset() { *m = CatalogRequest{} }
func (m *CatalogRequest) String() string { return proto.CompactTextString(m) }
func (*CatalogRequest) ProtoMessage() {}
func (m *CatalogRequest) GetCategory() *Category {
if m != nil {
return m.Category
}
return nil
}
func init() {
}
// Client API for CatalogService service
type CatalogServiceClient interface {
GetProductCatalog(ctx context.Context, in *CatalogRequest, opts ...grpc.CallOption) (*CatalogResponse, error)
}
type catalogServiceClient struct {
cc *grpc.ClientConn
}
func NewCatalogServiceClient(cc *grpc.ClientConn) CatalogServiceClient {
return &catalogServiceClient{cc}
}
func (c *catalogServiceClient) GetProductCatalog(ctx context.Context, in *CatalogRequest, opts ...grpc.CallOption) (*CatalogResponse, error) {
out := new(CatalogResponse)
err := grpc.Invoke(ctx, "/protos.CatalogService/GetProductCatalog", in, out, c.cc, opts...)
if err != nil {
return nil, err
}
return out, nil
}
// Server API for CatalogService service
type CatalogServiceServer interface {
GetProductCatalog(context.Context, *CatalogRequest) (*CatalogResponse, error)
}
func RegisterCatalogServiceServer(s *grpc.Server, srv CatalogServiceServer) {
s.RegisterService(&_CatalogService_serviceDesc, srv)
}
func _CatalogService_GetProductCatalog_Handler(srv interface{}, ctx context.Context, buf []byte) (proto.Message, error) {
in := new(CatalogRequest)
if err := proto.Unmarshal(buf, in); err != nil {
return nil, err
}
out, err := srv.(CatalogServiceServer).GetProductCatalog(ctx, in)
if err != nil {
return nil, err
}
return out, nil
}
var _CatalogService_serviceDesc = grpc.ServiceDesc{
ServiceName: "protos.CatalogService",
HandlerType: (*CatalogServiceServer)(nil),
Methods: []grpc.MethodDesc{
{
MethodName: "GetProductCatalog",
Handler: _CatalogService_GetProductCatalog_Handler,
},
},
Streams: []grpc.StreamDesc{},
}
这是RecommendationService.pg.go
// Code generated by protoc-gen-go.
// source: RecommendationService.proto
// DO NOT EDIT!
package protos
import proto "github.com/golang/protobuf/proto"
import (
context "golang.org/x/net/context"
grpc "google.golang.org/grpc"
)
// Reference imports to suppress errors if they are not otherwise used.
var _ context.Context
var _ grpc.ClientConn
// Reference imports to suppress errors if they are not otherwise used.
var _ = proto.Marshal
type RecommendationResponse struct {
Result []*RecommendationResponse_Recommendation `protobuf:"bytes,1,rep,name=result" json:"result,omitempty"`
}
func (m *RecommendationResponse) Reset() { *m = RecommendationResponse{} }
func (m *RecommendationResponse) String() string { return proto.CompactTextString(m) }
func (*RecommendationResponse) ProtoMessage() {}
func (m *RecommendationResponse) GetResult() []*RecommendationResponse_Recommendation {
if m != nil {
return m.Result
}
return nil
}
type RecommendationResponse_Recommendation struct {
Rating int32 `protobuf:"varint,1,opt,name=rating" json:"rating,omitempty"`
Productid int32 `protobuf:"varint,2,opt,name=productid" json:"productid,omitempty"`
}
func (m *RecommendationResponse_Recommendation) Reset() { *m = RecommendationResponse_Recommendation{} }
func (m *RecommendationResponse_Recommendation) String() string { return proto.CompactTextString(m) }
func (*RecommendationResponse_Recommendation) ProtoMessage() {}
func init() {
}
// Client API for RecommendationService service
type RecommendationServiceClient interface {
GetRecommendations(ctx context.Context, in *Product, opts ...grpc.CallOption) (*RecommendationResponse, error)
}
type recommendationServiceClient struct {
cc *grpc.ClientConn
}
func NewRecommendationServiceClient(cc *grpc.ClientConn) RecommendationServiceClient {
return &recommendationServiceClient{cc}
}
func (c *recommendationServiceClient) GetRecommendations(ctx context.Context, in *Product, opts ...grpc.CallOption) (*RecommendationResponse, error) {
out := new(RecommendationResponse)
err := grpc.Invoke(ctx, "/protos.RecommendationService/GetRecommendations", in, out, c.cc, opts...)
if err != nil {
return nil, err
}
return out, nil
}
// Server API for RecommendationService service
type RecommendationServiceServer interface {
GetRecommendations(context.Context, *Product) (*RecommendationResponse, error)
}
func RegisterRecommendationServiceServer(s *grpc.Server, srv RecommendationServiceServer) {
s.RegisterService(&_RecommendationService_serviceDesc, srv)
}
func _RecommendationService_GetRecommendations_Handler(srv interface{}, ctx context.Context, buf []byte) (proto.Message, error) {
in := new(Product)
if err := proto.Unmarshal(buf, in); err != nil {
return nil, err
}
out, err := srv.(RecommendationServiceServer).GetRecommendations(ctx, in)
if err != nil {
return nil, err
}
return out, nil
}
var _RecommendationService_serviceDesc = grpc.ServiceDesc{
ServiceName: "protos.RecommendationService",
HandlerType: (*RecommendationServiceServer)(nil),
Methods: []grpc.MethodDesc{
{
MethodName: "GetRecommendations",
Handler: _RecommendationService_GetRecommendations_Handler,
},
},
Streams: []grpc.StreamDesc{},
}
答案 0 :(得分:8)
基本上你的protoc-gen-go与grpc的版本不匹配。因此,将它们同步到最新版本并重新安装protoc-gen-go将解决问题:
go get -u github.com/golang/protobuf/
cd github.com/golang/protobuf/
make
go get -u github.com/grpc/grpc-go
答案 1 :(得分:2)
对于遇到同样问题的人,我所做的只是改变我构建原型文件的方式。博客页面上有一条评论突出显示了一些缺失的步骤,我跟着它并执行了以下protoc命令来生成原型文件中的代码:
protoc --go_out=plugins=grpc:. *.proto
我在我的proto文件的目录中运行了这个命令,然后在我的main.go文件上进行了构建,现在一切正常。
答案 2 :(得分:0)
我遇到了同样的问题并重新安装或新命令似乎不起作用。
但是:如果你改变了
codec grpc.Codec, buf []byte
在Handler中定义为:
dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor
和
codec.Unmarshal(buf, in)
进入
dec(in)
(全部在.pb.go文件的Handler定义中)
它似乎有效。更改此文件当然不是最佳选择,每次重新编译它都会覆盖您的更改,但至少有一个解决方法,直到我弄清楚我搞砸了什么。