Go语言grpc通过protobuf实现远程调用官方Demo(examples)结构分析

#1.官方的Examples结构:
Go语言grpc通过protobuf实现远程调用官方Demo(examples)结构分析
文章图片

helloworld目录结构 Go语言grpc通过protobuf实现远程调用官方Demo(examples)结构分析
文章图片

#1.1helloword.proto 文件内容

syntax = "proto3"; option java_multiple_files = true; option java_package = "io.grpc.examples.helloworld"; option java_outer_classname = "HelloWorldProto"; package helloworld; // The greeting service definition. service Greeter { // Sends a greeting rpc SayHello (HelloRequest) returns (HelloReply) {} }// The request message containing the user's name. message HelloRequest { string name = 1; }// The response message containing the greetings message HelloReply { string message = 1; }

#1.2通过protoc命令自动生成xxx.pb.go
命令: protoc --go_out=plugins=grpc:./生成文件存放的位置 [一个空格]./xxx.proto文件的位置

helloword.pb.go文件内容
// Code generated by protoc-gen-go. DO NOT EDIT. // source: helloworld.protopackage helloworldimport ( context "context" fmt "fmt" proto "github.com/golang/protobuf/proto" grpc "google.golang.org/grpc" codes "google.golang.org/grpc/codes" status "google.golang.org/grpc/status" math "math" )// Reference imports to suppress errors if they are not otherwise used. var _ = proto.Marshal var _ = fmt.Errorf var _ = math.Inf// This is a compile-time assertion to ensure that this generated file // is compatible with the proto package it is being compiled against. // A compilation error at this line likely means your copy of the // proto package needs to be updated. const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package// The request message containing the user's name. type HelloRequest struct { Namestring`protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized[]byte`json:"-"` XXX_sizecacheint32`json:"-"` }func (m *HelloRequest) Reset(){ *m = HelloRequest{} } func (m *HelloRequest) String() string { return proto.CompactTextString(m) } func (*HelloRequest) ProtoMessage(){} func (*HelloRequest) Descriptor() ([]byte, []int) { return fileDescriptor_17b8c58d586b62f2, []int{0} }func (m *HelloRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_HelloRequest.Unmarshal(m, b) } func (m *HelloRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_HelloRequest.Marshal(b, m, deterministic) } func (m *HelloRequest) XXX_Merge(src proto.Message) { xxx_messageInfo_HelloRequest.Merge(m, src) } func (m *HelloRequest) XXX_Size() int { return xxx_messageInfo_HelloRequest.Size(m) } func (m *HelloRequest) XXX_DiscardUnknown() { xxx_messageInfo_HelloRequest.DiscardUnknown(m) }var xxx_messageInfo_HelloRequest proto.InternalMessageInfofunc (m *HelloRequest) GetName() string { if m != nil { return m.Name } return "" }// The response message containing the greetings type HelloReply struct { Messagestring`protobuf:"bytes,1,opt,name=message,proto3" json:"message,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized[]byte`json:"-"` XXX_sizecacheint32`json:"-"` }func (m *HelloReply) Reset(){ *m = HelloReply{} } func (m *HelloReply) String() string { return proto.CompactTextString(m) } func (*HelloReply) ProtoMessage(){} func (*HelloReply) Descriptor() ([]byte, []int) { return fileDescriptor_17b8c58d586b62f2, []int{1} }func (m *HelloReply) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_HelloReply.Unmarshal(m, b) } func (m *HelloReply) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_HelloReply.Marshal(b, m, deterministic) } func (m *HelloReply) XXX_Merge(src proto.Message) { xxx_messageInfo_HelloReply.Merge(m, src) } func (m *HelloReply) XXX_Size() int { return xxx_messageInfo_HelloReply.Size(m) } func (m *HelloReply) XXX_DiscardUnknown() { xxx_messageInfo_HelloReply.DiscardUnknown(m) }var xxx_messageInfo_HelloReply proto.InternalMessageInfofunc (m *HelloReply) GetMessage() string { if m != nil { return m.Message } return "" }func init() { proto.RegisterType((*HelloRequest)(nil), "helloworld.HelloRequest") proto.RegisterType((*HelloReply)(nil), "helloworld.HelloReply") }func init() { proto.RegisterFile("helloworld.proto", fileDescriptor_17b8c58d586b62f2) }var fileDescriptor_17b8c58d586b62f2 = []byte{ // 175 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x12, 0xc8, 0x48, 0xcd, 0xc9, 0xc9, 0x2f, 0xcf, 0x2f, 0xca, 0x49, 0xd1, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0xe2, 0x42, 0x88, 0x28, 0x29, 0x71, 0xf1, 0x78, 0x80, 0x78, 0x41, 0xa9, 0x85, 0xa5, 0xa9, 0xc5, 0x25, 0x42, 0x42, 0x5c, 0x2c, 0x79, 0x89, 0xb9, 0xa9, 0x12, 0x8c, 0x0a, 0x8c, 0x1a, 0x9c, 0x41, 0x60, 0xb6, 0x92, 0x1a, 0x17, 0x17, 0x54, 0x4d, 0x41, 0x4e, 0xa5, 0x90, 0x04, 0x17, 0x7b, 0x6e, 0x6a, 0x71, 0x71, 0x62, 0x3a, 0x4c, 0x11, 0x8c, 0x6b, 0xe4, 0xc9, 0xc5, 0xee, 0x5e, 0x94, 0x9a, 0x5a, 0x92, 0x5a, 0x24, 0x64, 0xc7, 0xc5, 0x11, 0x9c, 0x58, 0x09, 0xd6, 0x25, 0x24, 0xa1, 0x87, 0xe4, 0x02, 0x64, 0xcb, 0xa4, 0xc4, 0xb0, 0xc8, 0x14, 0xe4, 0x54, 0x2a, 0x31, 0x38, 0x19, 0x70, 0x49, 0x67, 0xe6, 0xeb, 0xa5, 0x17, 0x15, 0x24, 0xeb, 0xa5, 0x56, 0x24, 0xe6, 0x16, 0xe4, 0xa4, 0x16, 0x23, 0xa9, 0x75, 0xe2, 0x07, 0x2b, 0x0e, 0x07, 0xb1, 0x03, 0x40, 0x5e, 0x0a, 0x60, 0x4c, 0x62, 0x03, 0xfb, 0xcd, 0x18, 0x10, 0x00, 0x00, 0xff, 0xff, 0x0f, 0xb7, 0xcd, 0xf2, 0xef, 0x00, 0x00, 0x00, }// Reference imports to suppress errors if they are not otherwise used. var _ context.Context var _ grpc.ClientConn// This is a compile-time assertion to ensure that this generated file // is compatible with the grpc package it is being compiled against. const _ = grpc.SupportPackageIsVersion4// GreeterClient is the client API for Greeter service. // // For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream. type GreeterClient interface { // Sends a greeting SayHello(ctx context.Context, in *HelloRequest, opts ...grpc.CallOption) (*HelloReply, error) }type greeterClient struct { cc *grpc.ClientConn }func NewGreeterClient(cc *grpc.ClientConn) GreeterClient { return &greeterClient{cc} }func (c *greeterClient) SayHello(ctx context.Context, in *HelloRequest, opts ...grpc.CallOption) (*HelloReply, error) { out := new(HelloReply) err := c.cc.Invoke(ctx, "/helloworld.Greeter/SayHello", in, out, opts...) if err != nil { return nil, err } return out, nil }// GreeterServer is the server API for Greeter service. type GreeterServer interface { // Sends a greeting SayHello(context.Context, *HelloRequest) (*HelloReply, error) }// UnimplementedGreeterServer can be embedded to have forward compatible implementations. type UnimplementedGreeterServer struct { }func (*UnimplementedGreeterServer) SayHello(ctx context.Context, req *HelloRequest) (*HelloReply, error) { return nil, status.Errorf(codes.Unimplemented, "method SayHello not implemented") }func RegisterGreeterServer(s *grpc.Server, srv GreeterServer) { s.RegisterService(&_Greeter_serviceDesc, srv) }func _Greeter_SayHello_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(HelloRequest) if err := dec(in); err != nil { return nil, err } if interceptor == nil { return srv.(GreeterServer).SayHello(ctx, in) } info := &grpc.UnaryServerInfo{ Server:srv, FullMethod: "/helloworld.Greeter/SayHello", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(GreeterServer).SayHello(ctx, req.(*HelloRequest)) } return interceptor(ctx, in, info, handler) }var _Greeter_serviceDesc = grpc.ServiceDesc{ ServiceName: "helloworld.Greeter", HandlerType: (*GreeterServer)(nil), Methods: []grpc.MethodDesc{ { MethodName: "SayHello", Handler:_Greeter_SayHello_Handler, }, }, Streams:[]grpc.StreamDesc{}, Metadata: "helloworld.proto", }

#2.准备服务(Server)
【Go语言grpc通过protobuf实现远程调用官方Demo(examples)结构分析】Go语言grpc通过protobuf实现远程调用官方Demo(examples)结构分析
文章图片

/* * * Copyright 2015 gRPC authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * *http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * *///go:generate protoc -I ../helloworld --go_out=plugins=grpc:../helloworld ../helloworld/helloworld.proto// Package main implements a server for Greeter service. package mainimport ( "context" "log" "net" "google.golang.org/grpc" // pb[空格]"xxxx" 为导入的包取的别名,方便使用 pb "google.golang.org/grpc/examples/helloworld/helloworld" )const ( port = ":50051" )// server is used to implement helloworld.GreeterServer. type server struct { pb.UnimplementedGreeterServer }// SayHello implements helloworld.GreeterServer func (s *server) SayHello(ctx context.Context, in *pb.HelloRequest) (*pb.HelloReply, error) { log.Printf("Received: %v", in.GetName()) return &pb.HelloReply{Message: "Hello " + in.GetName()}, nil }// 启动服务 func main() { lis, err := net.Listen("tcp", port) if err != nil { log.Fatalf("failed to listen: %v", err) } s := grpc.NewServer() pb.RegisterGreeterServer(s, &server{}) if err := s.Serve(lis); err != nil { log.Fatalf("failed to serve: %v", err) } }

#3.准备客户端/调用方(client)
Go语言grpc通过protobuf实现远程调用官方Demo(examples)结构分析
文章图片

/* * * Copyright 2015 gRPC authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * *http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */// Package main implements a client for Greeter service. package mainimport ( "context" "log" "os" "time" "google.golang.org/grpc" pb "google.golang.org/grpc/examples/helloworld/helloworld" )const ( address= "localhost:50051" defaultName = "world" )// 客户端/调用方 调用 func main() { // Set up a connection to the server. conn, err := grpc.Dial(address, grpc.WithInsecure(), grpc.WithBlock()) if err != nil { log.Fatalf("did not connect: %v", err) } defer conn.Close() c := pb.NewGreeterClient(conn) // Contact the server and print out its response. name := defaultName if len(os.Args) > 1 { name = os.Args[1] } ctx, cancel := context.WithTimeout(context.Background(), time.Second) defer cancel() r, err := c.SayHello(ctx, &pb.HelloRequest{Name: name}) if err != nil { log.Fatalf("could not greet: %v", err) } log.Printf("Greeting: %s", r.GetMessage()) }

先启动Serve下面main.go的主方法,再启动client下面main.go的main方法
得到如下打印结果:
Go语言grpc通过protobuf实现远程调用官方Demo(examples)结构分析
文章图片

官方案例_客户端调用服务端成功
#4.自己实现(未成功/未解决/不知道原因)
#4.1目录结构 Go语言grpc通过protobuf实现远程调用官方Demo(examples)结构分析
文章图片

#4.2message.proto文件内容
syntax = "proto3"; package message; // 订单请求参数 message OrderRequest { string orderId = 1; int64 timeStamp =2; }// 订单信息 message OrderInfo{ string OrderId =1; string OrderName =2; string OrderStatus =3; }// 订单服务service定义 service OrderService{ rpc GerOrderInfo(OrderRequest) returns (OrderInfo); }

#4.3message.pb.go文件内容
// Code generated by protoc-gen-go. DO NOT EDIT. // source: message/message.protopackage messageimport ( context "context" fmt "fmt" proto "github.com/golang/protobuf/proto" grpc "google.golang.org/grpc" codes "google.golang.org/grpc/codes" status "google.golang.org/grpc/status" math "math" )// Reference imports to suppress errors if they are not otherwise used. var _ = proto.Marshal var _ = fmt.Errorf var _ = math.Inf// This is a compile-time assertion to ensure that this generated file // is compatible with the proto package it is being compiled against. // A compilation error at this line likely means your copy of the // proto package needs to be updated. const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package// 订单请求参数 type OrderRequest struct { OrderIdstring`protobuf:"bytes,1,opt,name=orderId,proto3" json:"orderId,omitempty"` TimeStampint64`protobuf:"varint,2,opt,name=timeStamp,proto3" json:"timeStamp,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized[]byte`json:"-"` XXX_sizecacheint32`json:"-"` }func (m *OrderRequest) Reset(){ *m = OrderRequest{} } func (m *OrderRequest) String() string { return proto.CompactTextString(m) } func (*OrderRequest) ProtoMessage(){} func (*OrderRequest) Descriptor() ([]byte, []int) { return fileDescriptor_ebceca9e8703e37f, []int{0} }func (m *OrderRequest) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_OrderRequest.Unmarshal(m, b) } func (m *OrderRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_OrderRequest.Marshal(b, m, deterministic) } func (m *OrderRequest) XXX_Merge(src proto.Message) { xxx_messageInfo_OrderRequest.Merge(m, src) } func (m *OrderRequest) XXX_Size() int { return xxx_messageInfo_OrderRequest.Size(m) } func (m *OrderRequest) XXX_DiscardUnknown() { xxx_messageInfo_OrderRequest.DiscardUnknown(m) }var xxx_messageInfo_OrderRequest proto.InternalMessageInfofunc (m *OrderRequest) GetOrderId() string { if m != nil { return m.OrderId } return "" }func (m *OrderRequest) GetTimeStamp() int64 { if m != nil { return m.TimeStamp } return 0 }// 订单信息 type OrderInfo struct { OrderIdstring`protobuf:"bytes,1,opt,name=OrderId,proto3" json:"OrderId,omitempty"` OrderNamestring`protobuf:"bytes,2,opt,name=OrderName,proto3" json:"OrderName,omitempty"` OrderStatusstring`protobuf:"bytes,3,opt,name=OrderStatus,proto3" json:"OrderStatus,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized[]byte`json:"-"` XXX_sizecacheint32`json:"-"` }func (m *OrderInfo) Reset(){ *m = OrderInfo{} } func (m *OrderInfo) String() string { return proto.CompactTextString(m) } func (*OrderInfo) ProtoMessage(){} func (*OrderInfo) Descriptor() ([]byte, []int) { return fileDescriptor_ebceca9e8703e37f, []int{1} }func (m *OrderInfo) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_OrderInfo.Unmarshal(m, b) } func (m *OrderInfo) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_OrderInfo.Marshal(b, m, deterministic) } func (m *OrderInfo) XXX_Merge(src proto.Message) { xxx_messageInfo_OrderInfo.Merge(m, src) } func (m *OrderInfo) XXX_Size() int { return xxx_messageInfo_OrderInfo.Size(m) } func (m *OrderInfo) XXX_DiscardUnknown() { xxx_messageInfo_OrderInfo.DiscardUnknown(m) }var xxx_messageInfo_OrderInfo proto.InternalMessageInfofunc (m *OrderInfo) GetOrderId() string { if m != nil { return m.OrderId } return "" }func (m *OrderInfo) GetOrderName() string { if m != nil { return m.OrderName } return "" }func (m *OrderInfo) GetOrderStatus() string { if m != nil { return m.OrderStatus } return "" }func init() { proto.RegisterType((*OrderRequest)(nil), "message.OrderRequest") proto.RegisterType((*OrderInfo)(nil), "message.OrderInfo") }func init() { proto.RegisterFile("message/message.proto", fileDescriptor_ebceca9e8703e37f) }var fileDescriptor_ebceca9e8703e37f = []byte{ // 187 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x12, 0xcd, 0x4d, 0x2d, 0x2e, 0x4e, 0x4c, 0x4f, 0xd5, 0x87, 0xd2, 0x7a, 0x05, 0x45, 0xf9, 0x25, 0xf9, 0x42, 0xec, 0x50, 0xae, 0x92, 0x1b, 0x17, 0x8f, 0x7f, 0x51, 0x4a, 0x6a, 0x51, 0x50, 0x6a, 0x61, 0x69, 0x6a, 0x71, 0x89, 0x90, 0x04, 0x17, 0x7b, 0x3e, 0x88, 0xef, 0x99, 0x22, 0xc1, 0xa8, 0xc0, 0xa8, 0xc1, 0x19, 0x04, 0xe3, 0x0a, 0xc9, 0x70, 0x71, 0x96, 0x64, 0xe6, 0xa6, 0x06, 0x97, 0x24, 0xe6, 0x16, 0x48, 0x30, 0x29, 0x30, 0x6a, 0x30, 0x07, 0x21, 0x04, 0x94, 0x52, 0xb9, 0x38, 0xc1, 0xe6, 0x78, 0xe6, 0xa5, 0xe5, 0x83, 0x0c, 0xf1, 0x47, 0x35, 0xc4, 0x1f, 0x61, 0x08, 0x98, 0xe9, 0x97, 0x98, 0x9b, 0x0a, 0x36, 0x84, 0x33, 0x08, 0x21, 0x20, 0xa4, 0xc0, 0xc5, 0x0d, 0xe6, 0x04, 0x97, 0x24, 0x96, 0x94, 0x16, 0x4b, 0x30, 0x83, 0xe5, 0x91, 0x85, 0x8c, 0x3c, 0xa1, 0xce, 0x0d, 0x4e, 0x2d, 0x2a, 0xcb, 0x4c, 0x4e, 0x15, 0xb2, 0xe4, 0xe2, 0x71, 0x4f, 0x2d, 0x42, 0xd8, 0x2c, 0xaa, 0x07, 0xf3, 0x27, 0xb2, 0xaf, 0xa4, 0x84, 0x50, 0x85, 0x41, 0x4a, 0x93, 0xd8, 0xc0, 0x21, 0x61, 0x0c, 0x08, 0x00, 0x00, 0xff, 0xff, 0x97, 0x12, 0x0f, 0x48, 0x22, 0x01, 0x00, 0x00, }// Reference imports to suppress errors if they are not otherwise used. var _ context.Context var _ grpc.ClientConn// This is a compile-time assertion to ensure that this generated file // is compatible with the grpc package it is being compiled against. const _ = grpc.SupportPackageIsVersion4// OrderServiceClient is the client API for OrderService service. // // For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream. type OrderServiceClient interface { GerOrderInfo(ctx context.Context, in *OrderRequest, opts ...grpc.CallOption) (*OrderInfo, error) }type orderServiceClient struct { cc *grpc.ClientConn }func NewOrderServiceClient(cc *grpc.ClientConn) OrderServiceClient { return &orderServiceClient{cc} }func (c *orderServiceClient) GerOrderInfo(ctx context.Context, in *OrderRequest, opts ...grpc.CallOption) (*OrderInfo, error) { out := new(OrderInfo) err := c.cc.Invoke(ctx, "/message.OrderService/GerOrderInfo", in, out, opts...) if err != nil { return nil, err } return out, nil }// OrderServiceServer is the server API for OrderService service. type OrderServiceServer interface { GerOrderInfo(context.Context, *OrderRequest) (*OrderInfo, error) }// UnimplementedOrderServiceServer can be embedded to have forward compatible implementations. type UnimplementedOrderServiceServer struct { }func (*UnimplementedOrderServiceServer) GerOrderInfo(ctx context.Context, req *OrderRequest) (*OrderInfo, error) { return nil, status.Errorf(codes.Unimplemented, "method GerOrderInfo not implemented") }func RegisterOrderServiceServer(s *grpc.Server, srv *OrderServiceImpl) { s.RegisterService(&_OrderService_serviceDesc, srv) }func _OrderService_GerOrderInfo_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(OrderRequest) if err := dec(in); err != nil { return nil, err } if interceptor == nil { return srv.(OrderServiceServer).GerOrderInfo(ctx, in) } info := &grpc.UnaryServerInfo{ Server:srv, FullMethod: "/message.OrderService/GerOrderInfo", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(OrderServiceServer).GerOrderInfo(ctx, req.(*OrderRequest)) } return interceptor(ctx, in, info, handler) }var _OrderService_serviceDesc = grpc.ServiceDesc{ ServiceName: "message.OrderService", HandlerType: (*OrderServiceServer)(nil), Methods: []grpc.MethodDesc{ { MethodName: "GerOrderInfo", Handler:_OrderService_GerOrderInfo_Handler, }, }, Streams:[]grpc.StreamDesc{}, Metadata: "message/message.proto", }

#4.3protoc命令生成message.pb.go文件
命令: protoc --go_out=plugins=grpc:./生成文件存放的位置 [一个空格]./xxx.proto文件的位置

#4.4准备服务(server)
package mainimport ( "context" "errors" "fmt" "google.golang.org/grpc" "net" "prototest2/messagee/message" pb "prototest2/messagee/message" "time" )type OrderServiceImpl struct { pb.UnimplementedOrderServiceServer }// 具体的方法实现 // GerOrderInfo(ctx context.Context, in *OrderRequest, opts ...grpc.CallOption) (*OrderInfo, error) func (os *OrderServiceImpl) GetOrderInfo(ctx context.Context, request *message.OrderRequest) (*message.OrderInfo, error) { // 准备测试数据/从数据库拿到数据/反正构造数据/不管从哪儿获取 orderMap := map[string]message.OrderInfo{ "201907300001": {OrderId: "201907300001", OrderName: "衣服", OrderStatus: "已付款"}, "201907310001": {OrderId: "201907310001", OrderName: "零食", OrderStatus: "已付款"}, "201907310002": {OrderId: "201907310002", OrderName: "食品", OrderStatus: "未付款"}, } var response *message.OrderInfo current := time.Now().Unix() if request.TimeStamp > current { *response = message.OrderInfo{OrderName: "", OrderId: "0", OrderStatus: "订单信息异常"} } else { result := orderMap[request.OrderId] if result.OrderId != "" { fmt.Println(result) return &result, nil } else { return nil, errors.New("server error ~~~~") } } return response, nil } func main() { orderService := OrderServiceImpl{} fmt.Printf("%T",orderService) server := grpc.NewServer() message.RegisterOrderServiceServer(server, new(OrderServiceImpl)) lis, err := net.Listen("tcp", "8090") if err != nil { panic(err.Error()) } server.Serve(lis)}

#4.5准备客户端(client)
package mainimport ( "context" "fmt" "google.golang.org/grpc" "prototest2/messagee/message" "time" )func main() { conn, err := grpc.Dial("localhost:8090", grpc.WithInsecure()) if err != nil { panic(err.Error()) } defer conn.Close() orderServiceClient := message.NewOrderServiceClient(conn) orderRequest := &message.OrderRequest{OrderId: "201907300001", TimeStamp: time.Now().Unix()} orderInfo, err := orderServiceClient.GerOrderInfo(context.Background(), orderRequest) if orderInfo != nil { fmt.Println(orderInfo.GetOrderId()) fmt.Println(orderInfo.GetOrderName()) fmt.Println(orderInfo.GetOrderStatus()) } }

问题:
在启动服务的main()方法时,总是会报错误
Go语言grpc通过protobuf实现远程调用官方Demo(examples)结构分析
文章图片

追踪到代码位置为:
Go语言grpc通过protobuf实现远程调用官方Demo(examples)结构分析
文章图片

Go语言grpc通过protobuf实现远程调用官方Demo(examples)结构分析
文章图片

总结:
整个grpc中client/server/xxx.proto文件这些结构算是大概了解了,但是具体的实现,发现错误的解决能力却没啥!

    推荐阅读