1. 程式人生 > 其它 >golang func 入參為func_golang中使用gRPC以及四種通訊方式

golang func 入參為func_golang中使用gRPC以及四種通訊方式

技術標籤:golang func 入參為func

公眾號【Linux開發架構之路】

個人gitee:

零聲社群​gitee.com c11785a436587b8931f3959c5cb1852f.png

golang中使用gRPC

前期準備

go get -u "google.golang.org/grpc"
go get -u "google.golang.org/grpc/reflection"

例如我定義的檔案exporttask.proto:

// 微生活匯出服務
// 匯出功能介面
/*
    1、 建立任務模板
    2、 查詢、列出任務模板
    3、 刪除任務模板
    4、 新增匯出任務例項
    5、 查詢任務狀態
*/
syntax = "proto3";
// java 語法特別選項
option java_multiple_files = true;
option java_package = "io.grpc.welife.WshExportTask";
option java_outer_classname = "WshExportTask";
// 包名 golang包名,php中namespase,
package exporttask;
// 匯出任務服務定義
service ExportTask {
  // 建立任務模板
  rpc CreateTpl(WshExportTaskCreateTplReq) returns (WshExportTaskCreateTplRes) {}
  // 查詢任務模板
  rpc ListTpl(WshExportTaskListTplReq) returns (WshExportTaskListTplRes) {}
}
// 列舉型別,必須從0開始,序號可跨越。同一包下不能重名,所以加字首來區別
enum WshExportTplStatus {
    TPL_INITED = 0;
    TPL_NORMAL = 1;
    TPL_DELETED = 9;
}
enum WshExportFormat {
    FMT_DEFAULT = 0;
    FMT_CSV = 1;
    FMT_XLS = 2;
}
message WshExportTpl {
    string etplName = 1;
    string etplTag = 2;
    WshExportFormat etplOutputFormat = 3;
    string etplOutputColumns = 4;
    string etplExpr = 5;
    int32 etplId = 6;
    int32 etplExecTimes = 7;
    int32 etplExecOkTimes = 8;
    int32 etplStatus = 9;
    string etplCreated = 10;
    string etplUpdated = 11;
    string etplDeleted = 12;
    int32 operatorId = 13;
}
message WshExportTaskCreateTplReq {
    string etplName = 1;
    string etplTag = 2;
    string etplExpr = 3;
    string etplOutputColumns = 4;
    WshExportFormat etplOutputFormat = 5;
    int32 operatorId = 6;
}
message WshExportTaskCreateTplRes {
    string errCode = 1;
    string errMsg = 2;
    WshExportTpl data = 3;
}
message WshExportTaskListTplReq {
    int32 etplId = 1;
    string etplName = 2;
    string etplTag = 3;
}
// repeated 表示陣列
message WshExportTaskListTplRes {
    string errCode = 1;
    string errMsg = 2;
    repeated WshExportTpl data = 3;
}

使用protoc命令生成golang對應的rpc程式碼:

#格式 protoc --go_out=plugins=grpc:{go程式碼輸出路徑} {proto檔案}
protoc --go_out=plugins=grpc:./ ./exporttask.proto

生成對應當exporttask.pb.go

// Code generated by protoc-gen-go. DO NOT EDIT.
// source: exporttask.proto
/*
Package exporttask is a generated protocol buffer package.
包名 golang包名,php中namespase,
It is generated from these files:
    exporttask.proto
It has these top-level messages:
    WshExportTpl
    WshExportTaskCreateTplReq
    WshExportTaskCreateTplRes
    WshExportTaskListTplReq
    WshExportTaskListTplRes
*/
package exporttask
import proto "github.com/golang/protobuf/proto"
import fmt "fmt"
import math "math"
import (
    context "golang.org/x/net/context"
    grpc "google.golang.org/grpc"
)
// 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.ProtoPackageIsVersion2 // please upgrade the proto package
// 列舉型別,必須從0開始,序號可跨越。同一包下不能重名,所以加字首來區別
type WshExportTplStatus int32
const (
    WshExportTplStatus_TPL_INITED  WshExportTplStatus = 0
    WshExportTplStatus_TPL_NORMAL  WshExportTplStatus = 1
    WshExportTplStatus_TPL_DELETED WshExportTplStatus = 9
)
var WshExportTplStatus_name = map[int32]string{
    0: "TPL_INITED",
    1: "TPL_NORMAL",
    9: "TPL_DELETED",
}
var WshExportTplStatus_value = map[string]int32{
    "TPL_INITED":  0,
    "TPL_NORMAL":  1,
    "TPL_DELETED": 9,
}
func (x WshExportTplStatus) String() string {
    return proto.EnumName(WshExportTplStatus_name, int32(x))
}
func (WshExportTplStatus) EnumDescriptor() ([]byte, []int) { return fileDescriptor0, []int{0} }
type WshExportFormat int32
const (
    WshExportFormat_FMT_DEFAULT WshExportFormat = 0
    WshExportFormat_FMT_CSV     WshExportFormat = 1
    WshExportFormat_FMT_XLS     WshExportFormat = 2
)
var WshExportFormat_name = map[int32]string{
    0: "FMT_DEFAULT",
    1: "FMT_CSV",
    2: "FMT_XLS",
}
var WshExportFormat_value = map[string]int32{
    "FMT_DEFAULT": 0,
    "FMT_CSV":     1,
    "FMT_XLS":     2,
}
func (x WshExportFormat) String() string {
    return proto.EnumName(WshExportFormat_name, int32(x))
}
func (WshExportFormat) EnumDescriptor() ([]byte, []int) { return fileDescriptor0, []int{1} }
type WshExportTpl struct {
    EtplName          string          `protobuf:"bytes,1,opt,name=etplName" json:"etplName,omitempty"`
    EtplTag           string          `protobuf:"bytes,2,opt,name=etplTag" json:"etplTag,omitempty"`
    EtplOutputFormat  WshExportFormat `protobuf:"varint,3,opt,name=etplOutputFormat,enum=exporttask.WshExportFormat" json:"etplOutputFormat,omitempty"`
    EtplOutputColumns string          `protobuf:"bytes,4,opt,name=etplOutputColumns" json:"etplOutputColumns,omitempty"`
    EtplExpr          string          `protobuf:"bytes,5,opt,name=etplExpr" json:"etplExpr,omitempty"`
    EtplId            int32           `protobuf:"varint,6,opt,name=etplId" json:"etplId,omitempty"`
    EtplExecTimes     int32           `protobuf:"varint,7,opt,name=etplExecTimes" json:"etplExecTimes,omitempty"`
    EtplExecOkTimes   int32           `protobuf:"varint,8,opt,name=etplExecOkTimes" json:"etplExecOkTimes,omitempty"`
    EtplStatus        int32           `protobuf:"varint,9,opt,name=etplStatus" json:"etplStatus,omitempty"`
    EtplCreated       string          `protobuf:"bytes,10,opt,name=etplCreated" json:"etplCreated,omitempty"`
    EtplUpdated       string          `protobuf:"bytes,11,opt,name=etplUpdated" json:"etplUpdated,omitempty"`
    EtplDeleted       string          `protobuf:"bytes,12,opt,name=etplDeleted" json:"etplDeleted,omitempty"`
    OperatorId        int32           `protobuf:"varint,13,opt,name=operatorId" json:"operatorId,omitempty"`
}
func (m *WshExportTpl) Reset()                    { *m = WshExportTpl{} }
func (m *WshExportTpl) String() string            { return proto.CompactTextString(m) }
func (*WshExportTpl) ProtoMessage()               {}
func (*WshExportTpl) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{0} }
func (m *WshExportTpl) GetEtplName() string {
    if m != nil {
        return m.EtplName
    }
    return ""
}
func (m *WshExportTpl) GetEtplTag() string {
    if m != nil {
        return m.EtplTag
    }
    return ""
}
func (m *WshExportTpl) GetEtplOutputFormat() WshExportFormat {
    if m != nil {
        return m.EtplOutputFormat
    }
    return WshExportFormat_FMT_DEFAULT
}
func (m *WshExportTpl) GetEtplOutputColumns() string {
    if m != nil {
        return m.EtplOutputColumns
    }
    return ""
}
func (m *WshExportTpl) GetEtplExpr() string {
    if m != nil {
        return m.EtplExpr
    }
    return ""
}
func (m *WshExportTpl) GetEtplId() int32 {
    if m != nil {
        return m.EtplId
    }
    return 0
}
func (m *WshExportTpl) GetEtplExecTimes() int32 {
    if m != nil {
        return m.EtplExecTimes
    }
    return 0
}
func (m *WshExportTpl) GetEtplExecOkTimes() int32 {
    if m != nil {
        return m.EtplExecOkTimes
    }
    return 0
}
func (m *WshExportTpl) GetEtplStatus() int32 {
    if m != nil {
        return m.EtplStatus
    }
    return 0
}
func (m *WshExportTpl) GetEtplCreated() string {
    if m != nil {
        return m.EtplCreated
    }
    return ""
}
func (m *WshExportTpl) GetEtplUpdated() string {
    if m != nil {
        return m.EtplUpdated
    }
    return ""
}
func (m *WshExportTpl) GetEtplDeleted() string {
    if m != nil {
        return m.EtplDeleted
    }
    return ""
}
func (m *WshExportTpl) GetOperatorId() int32 {
    if m != nil {
        return m.OperatorId
    }
    return 0
}
type WshExportTaskCreateTplReq struct {
    EtplName          string          `protobuf:"bytes,1,opt,name=etplName" json:"etplName,omitempty"`
    EtplTag           string          `protobuf:"bytes,2,opt,name=etplTag" json:"etplTag,omitempty"`
    EtplExpr          string          `protobuf:"bytes,3,opt,name=etplExpr" json:"etplExpr,omitempty"`
    EtplOutputColumns string          `protobuf:"bytes,4,opt,name=etplOutputColumns" json:"etplOutputColumns,omitempty"`
    EtplOutputFormat  WshExportFormat `protobuf:"varint,5,opt,name=etplOutputFormat,enum=exporttask.WshExportFormat" json:"etplOutputFormat,omitempty"`
    OperatorId        int32           `protobuf:"varint,6,opt,name=operatorId" json:"operatorId,omitempty"`
}
func (m *WshExportTaskCreateTplReq) Reset()                    { *m = WshExportTaskCreateTplReq{} }
func (m *WshExportTaskCreateTplReq) String() string            { return proto.CompactTextString(m) }
func (*WshExportTaskCreateTplReq) ProtoMessage()               {}
func (*WshExportTaskCreateTplReq) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{1} }
func (m *WshExportTaskCreateTplReq) GetEtplName() string {
    if m != nil {
        return m.EtplName
    }
    return ""
}
func (m *WshExportTaskCreateTplReq) GetEtplTag() string {
    if m != nil {
        return m.EtplTag
    }
    return ""
}
func (m *WshExportTaskCreateTplReq) GetEtplExpr() string {
    if m != nil {
        return m.EtplExpr
    }
    return ""
}
func (m *WshExportTaskCreateTplReq) GetEtplOutputColumns() string {
    if m != nil {
        return m.EtplOutputColumns
    }
    return ""
}
func (m *WshExportTaskCreateTplReq) GetEtplOutputFormat() WshExportFormat {
    if m != nil {
        return m.EtplOutputFormat
    }
    return WshExportFormat_FMT_DEFAULT
}
func (m *WshExportTaskCreateTplReq) GetOperatorId() int32 {
    if m != nil {
        return m.OperatorId
    }
    return 0
}
type WshExportTaskCreateTplRes struct {
    ErrCode string        `protobuf:"bytes,1,opt,name=errCode" json:"errCode,omitempty"`
    ErrMsg  string        `protobuf:"bytes,2,opt,name=errMsg" json:"errMsg,omitempty"`
    Data    *WshExportTpl `protobuf:"bytes,3,opt,name=data" json:"data,omitempty"`
}
func (m *WshExportTaskCreateTplRes) Reset()                    { *m = WshExportTaskCreateTplRes{} }
func (m *WshExportTaskCreateTplRes) String() string            { return proto.CompactTextString(m) }
func (*WshExportTaskCreateTplRes) ProtoMessage()               {}
func (*WshExportTaskCreateTplRes) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{2} }
func (m *WshExportTaskCreateTplRes) GetErrCode() string {
    if m != nil {
        return m.ErrCode
    }
    return ""
}
func (m *WshExportTaskCreateTplRes) GetErrMsg() string {
    if m != nil {
        return m.ErrMsg
    }
    return ""
}
func (m *WshExportTaskCreateTplRes) GetData() *WshExportTpl {
    if m != nil {
        return m.Data
    }
    return nil
}
type WshExportTaskListTplReq struct {
    EtplId   int32  `protobuf:"varint,1,opt,name=etplId" json:"etplId,omitempty"`
    EtplName string `protobuf:"bytes,2,opt,name=etplName" json:"etplName,omitempty"`
    EtplTag  string `protobuf:"bytes,3,opt,name=etplTag" json:"etplTag,omitempty"`
}
func (m *WshExportTaskListTplReq) Reset()                    { *m = WshExportTaskListTplReq{} }
func (m *WshExportTaskListTplReq) String() string            { return proto.CompactTextString(m) }
func (*WshExportTaskListTplReq) ProtoMessage()               {}
func (*WshExportTaskListTplReq) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{3} }
func (m *WshExportTaskListTplReq) GetEtplId() int32 {
    if m != nil {
        return m.EtplId
    }
    return 0
}
func (m *WshExportTaskListTplReq) GetEtplName() string {
    if m != nil {
        return m.EtplName
    }
    return ""
}
func (m *WshExportTaskListTplReq) GetEtplTag() string {
    if m != nil {
        return m.EtplTag
    }
    return ""
}
// repeated 表示陣列
type WshExportTaskListTplRes struct {
    ErrCode string          `protobuf:"bytes,1,opt,name=errCode" json:"errCode,omitempty"`
    ErrMsg  string          `protobuf:"bytes,2,opt,name=errMsg" json:"errMsg,omitempty"`
    Data    []*WshExportTpl `protobuf:"bytes,3,rep,name=data" json:"data,omitempty"`
}
func (m *WshExportTaskListTplRes) Reset()                    { *m = WshExportTaskListTplRes{} }
func (m *WshExportTaskListTplRes) String() string            { return proto.CompactTextString(m) }
func (*WshExportTaskListTplRes) ProtoMessage()               {}
func (*WshExportTaskListTplRes) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{4} }
func (m *WshExportTaskListTplRes) GetErrCode() string {
    if m != nil {
        return m.ErrCode
    }
    return ""
}
func (m *WshExportTaskListTplRes) GetErrMsg() string {
    if m != nil {
        return m.ErrMsg
    }
    return ""
}
func (m *WshExportTaskListTplRes) GetData() []*WshExportTpl {
    if m != nil {
        return m.Data
    }
    return nil
}
func init() {
    proto.RegisterType((*WshExportTpl)(nil), "exporttask.WshExportTpl")
    proto.RegisterType((*WshExportTaskCreateTplReq)(nil), "exporttask.WshExportTaskCreateTplReq")
    proto.RegisterType((*WshExportTaskCreateTplRes)(nil), "exporttask.WshExportTaskCreateTplRes")
    proto.RegisterType((*WshExportTaskListTplReq)(nil), "exporttask.WshExportTaskListTplReq")
    proto.RegisterType((*WshExportTaskListTplRes)(nil), "exporttask.WshExportTaskListTplRes")
    proto.RegisterEnum("exporttask.WshExportTplStatus", WshExportTplStatus_name, WshExportTplStatus_value)
    proto.RegisterEnum("exporttask.WshExportFormat", WshExportFormat_name, WshExportFormat_value)
}
// 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
// Client API for ExportTask service
type ExportTaskClient interface {
    // 建立任務模板
    CreateTpl(ctx context.Context, in *WshExportTaskCreateTplReq, opts ...grpc.CallOption) (*WshExportTaskCreateTplRes, error)
    // 查詢任務模板
    ListTpl(ctx context.Context, in *WshExportTaskListTplReq, opts ...grpc.CallOption) (*WshExportTaskListTplRes, error)
}
type exportTaskClient struct {
    cc *grpc.ClientConn
}
func NewExportTaskClient(cc *grpc.ClientConn) ExportTaskClient {
    return &exportTaskClient{cc}
}
func (c *exportTaskClient) CreateTpl(ctx context.Context, in *WshExportTaskCreateTplReq, opts ...grpc.CallOption) (*WshExportTaskCreateTplRes, error) {
    out := new(WshExportTaskCreateTplRes)
    err := grpc.Invoke(ctx, "/exporttask.ExportTask/CreateTpl", in, out, c.cc, opts...)
    if err != nil {
        return nil, err
    }
    return out, nil
}
func (c *exportTaskClient) ListTpl(ctx context.Context, in *WshExportTaskListTplReq, opts ...grpc.CallOption) (*WshExportTaskListTplRes, error) {
    out := new(WshExportTaskListTplRes)
    err := grpc.Invoke(ctx, "/exporttask.ExportTask/ListTpl", in, out, c.cc, opts...)
    if err != nil {
        return nil, err
    }
    return out, nil
}
// Server API for ExportTask service
type ExportTaskServer interface {
    // 建立任務模板
    CreateTpl(context.Context, *WshExportTaskCreateTplReq) (*WshExportTaskCreateTplRes, error)
    // 查詢任務模板
    ListTpl(context.Context, *WshExportTaskListTplReq) (*WshExportTaskListTplRes, error)
}
func RegisterExportTaskServer(s *grpc.Server, srv ExportTaskServer) {
    s.RegisterService(&_ExportTask_serviceDesc, srv)
}
func _ExportTask_CreateTpl_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
    in := new(WshExportTaskCreateTplReq)
    if err := dec(in); err != nil {
        return nil, err
    }
    if interceptor == nil {
        return srv.(ExportTaskServer).CreateTpl(ctx, in)
    }
    info := &grpc.UnaryServerInfo{
        Server:     srv,
        FullMethod: "/exporttask.ExportTask/CreateTpl",
    }
    handler := func(ctx context.Context, req interface{}) (interface{}, error) {
        return srv.(ExportTaskServer).CreateTpl(ctx, req.(*WshExportTaskCreateTplReq))
    }
    return interceptor(ctx, in, info, handler)
}
func _ExportTask_ListTpl_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
    in := new(WshExportTaskListTplReq)
    if err := dec(in); err != nil {
        return nil, err
    }
    if interceptor == nil {
        return srv.(ExportTaskServer).ListTpl(ctx, in)
    }
    info := &grpc.UnaryServerInfo{
        Server:     srv,
        FullMethod: "/exporttask.ExportTask/ListTpl",
    }
    handler := func(ctx context.Context, req interface{}) (interface{}, error) {
        return srv.(ExportTaskServer).ListTpl(ctx, req.(*WshExportTaskListTplReq))
    }
    return interceptor(ctx, in, info, handler)
}
var _ExportTask_serviceDesc = grpc.ServiceDesc{
    ServiceName: "exporttask.ExportTask",
    HandlerType: (*ExportTaskServer)(nil),
    Methods: []grpc.MethodDesc{
        {
            MethodName: "CreateTpl",
            Handler:    _ExportTask_CreateTpl_Handler,
        },
        {
            MethodName: "ListTpl",
            Handler:    _ExportTask_ListTpl_Handler,
        },
    },
    Streams:  []grpc.StreamDesc{},
    Metadata: "exporttask.proto",
}
func init() { proto.RegisterFile("exporttask.proto", fileDescriptor0) }
var fileDescriptor0 = []byte{
    // 550 bytes of a gzipped FileDescriptorProto
    0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0xa4, 0x54, 0x5f, 0x8f, 0xd2, 0x4e,
    0x14, 0xa5, 0xb0, 0xc0, 0x72, 0x59, 0x96, 0xfe, 0xe6, 0xe1, 0xe7, 0x88, 0xc6, 0x90, 0xaa, 0x09,
    0xd9, 0x6c, 0x30, 0xc1, 0x57, 0x5f, 0x76, 0xa1, 0x18, 0x92, 0x02, 0x1b, 0x28, 0x6a, 0xe2, 0xc3,
    0xa6, 0x6e, 0x47, 0x24, 0x14, 0x5b, 0x67, 0x86, 0xb8, 0xc6, 0x57, 0x3f, 0x98, 0x5f, 0xc6, 0xef,
    0x61, 0x66, 0xda, 0x61, 0x5a, 0xfe, 0xc4, 0x75, 0x7d, 0x9b, 0x73, 0xe6, 0x94, 0x7b, 0xef, 0x39,
    0x77, 0x00, 0x93, 0xdc, 0x46, 0x21, 0xe5, 0xdc, 0x63, 0xcb, 0x76, 0x44, 0x43, 0x1e, 0x22, 0xd0,
    0x8c, 0xf5, 0xab, 0x00, 0x27, 0x6f, 0xd9, 0x27, 0x5b, 0x32, 0x6e, 0x14, 0xa0, 0x06, 0x1c, 0x13,
    0x1e, 0x05, 0x23, 0x6f, 0x45, 0xb0, 0xd1, 0x34, 0x5a, 0x95, 0xc9, 0x06, 0x23, 0x0c, 0x65, 0x71,
    0x76, 0xbd, 0x39, 0xce, 0xcb, 0x2b, 0x05, 0xd1, 0x6b, 0x30, 0xc5, 0x71, 0xbc, 0xe6, 0xd1, 0x9a,
    0xf7, 0x43, 0xba, 0xf2, 0x38, 0x2e, 0x34, 0x8d, 0xd6, 0x69, 0xe7, 0x51, 0x3b, 0x55, 0x7f, 0x53,
    0x29, 0x96, 0x4c, 0x76, 0x3e, 0x42, 0xe7, 0xf0, 0x9f, 0xe6, 0xba, 0x61, 0xb0, 0x5e, 0x7d, 0x66,
    0xf8, 0x48, 0x16, 0xdb, 0xbd, 0x50, 0xcd, 0xda, 0xb7, 0x11, 0xc5, 0x45, 0xdd, 0xac, 0xc0, 0xe8,
    0x7f, 0x28, 0x89, 0xf3, 0xc0, 0xc7, 0xa5, 0xa6, 0xd1, 0x2a, 0x4e, 0x12, 0x84, 0x9e, 0x41, 0x2d,
    0xd6, 0x90, 0x1b, 0x77, 0xb1, 0x22, 0x0c, 0x97, 0xe5, 0x75, 0x96, 0x44, 0x2d, 0xa8, 0x2b, 0x62,
    0xbc, 0x8c, 0x75, 0xc7, 0x52, 0xb7, 0x4d, 0xa3, 0x27, 0x00, 0x82, 0x9a, 0x72, 0x8f, 0xaf, 0x19,
    0xae, 0x48, 0x51, 0x8a, 0x41, 0x4d, 0xa8, 0x0a, 0xd4, 0xa5, 0xc4, 0xe3, 0xc4, 0xc7, 0x20, 0xdb,
    0x4c, 0x53, 0x4a, 0x31, 0x8b, 0x7c, 0xa9, 0xa8, 0x6a, 0x45, 0x42, 0x29, 0x45, 0x8f, 0x04, 0x44,
    0x28, 0x4e, 0xb4, 0x22, 0xa1, 0x44, 0x17, 0x61, 0x44, 0xa8, 0xc7, 0x43, 0x3a, 0xf0, 0x71, 0x2d,
    0xee, 0x42, 0x33, 0xd6, 0x8f, 0x3c, 0x3c, 0xd4, 0x39, 0x7b, 0x6c, 0x19, 0x17, 0x77, 0xa3, 0x60,
    0x42, 0xbe, 0xdc, 0x33, 0xf4, 0xb4, 0xfb, 0x85, 0x2d, 0xf7, 0xff, 0x2e, 0xc7, 0x7d, 0xeb, 0x53,
    0xbc, 0xcf, 0xfa, 0x64, 0x6d, 0x28, 0xed, 0xd8, 0xf0, 0xfd, 0xb0, 0x0b, 0x4c, 0x4e, 0x4a, 0x69,
    0x37, 0xf4, 0x95, 0x09, 0x0a, 0xca, 0x5d, 0xa2, 0x74, 0xc8, 0x94, 0x05, 0x09, 0x42, 0xe7, 0x70,
    0xe4, 0x7b, 0xdc, 0x93, 0xd3, 0x57, 0x3b, 0x78, 0x6f, 0xaf, 0xe2, 0xc7, 0xa5, 0xca, 0x9a, 0xc3,
    0x83, 0x4c, 0x71, 0x67, 0xc1, 0x78, 0x12, 0x80, 0x5e, 0x56, 0x23, 0xb3, 0xac, 0xe9, 0x60, 0xf2,
    0x87, 0x83, 0x29, 0x64, 0x82, 0xb1, 0xbe, 0x1d, 0x2a, 0xf4, 0x6f, 0x33, 0x16, 0xfe, 0x3c, 0xe3,
    0x99, 0x0d, 0x28, 0xcd, 0x26, 0x6f, 0xe0, 0x14, 0xc0, 0xbd, 0x72, 0xae, 0x07, 0xa3, 0x81, 0x6b,
    0xf7, 0xcc, 0x9c, 0xc2, 0xa3, 0xf1, 0x64, 0x78, 0xe1, 0x98, 0x06, 0xaa, 0x43, 0x55, 0xe0, 0x9e,
    0xed, 0xd8, 0x42, 0x50, 0x39, 0x7b, 0x05, 0xf5, 0xad, 0xb0, 0x85, 0xa6, 0x3f, 0x74, 0xaf, 0x7b,
    0x76, 0xff, 0x62, 0xe6, 0xb8, 0x66, 0x0e, 0x55, 0xa1, 0x2c, 0x88, 0xee, 0xf4, 0x8d, 0x69, 0x28,
    0xf0, 0xce, 0x99, 0x9a, 0xf9, 0xce, 0x4f, 0x03, 0x40, 0x4f, 0x8f, 0xde, 0x43, 0x65, 0x93, 0x33,
    0x7a, 0xbe, 0x7f, 0x80, 0xad, 0x17, 0xd1, 0xb8, 0x93, 0x8c, 0x59, 0x39, 0x34, 0x83, 0x72, 0x62,
    0x2f, 0x7a, 0x7a, 0xf0, 0x1b, 0x9d, 0x74, 0xe3, 0x0e, 0x22, 0x66, 0xe5, 0x2e, 0x5f, 0xc0, 0xe3,
    0x45, 0xd8, 0x9e, 0xd3, 0xe8, 0xa6, 0xfd, 0x95, 0x04, 0x8b, 0x8f, 0x24, 0xab, 0xbd, 0xac, 0x65,
    0xe0, 0x95, 0xf1, 0xa1, 0x24, 0xff, 0xdb, 0x5f, 0xfe, 0x0e, 0x00, 0x00, 0xff, 0xff, 0x60, 0x9b,
    0xec, 0x89, 0xef, 0x05, 0x00, 0x00,
}

服務端實現proto中的介面:

package main
import (
    "log"
    //"net"
    svcExport "../../common/exporttask" // 包含上面的pb生成的go包
    "./model"
    _ "github.com/go-sql-driver/mysql"
    "golang.org/x/net/context"
    //"google.golang.org/grpc"
    //"google.golang.org/grpc/reflection"
)
// server 這個物件來實現 exporttask 包中的pb定義的rpc服務
// 實現的方式是將服務轉化成本地的資料庫操作
type server struct{}
func (s *server) CreateTpl(ctx context.Context, in *svcExport.WshExportTaskCreateTplReq) (res *svcExport.WshExportTaskCreateTplRes, err error) {
    res = new(svcExport.WshExportTaskCreateTplRes)
    res.Data = new(svcExport.WshExportTpl)
    var etplId int32 = 0
    etplId, err = model.CreateTpl(in.EtplName, in.EtplTag, in.EtplExpr, in.EtplOutputColumns, int32(in.EtplOutputFormat), in.OperatorId)
    //res.Data, err = model.GetTpl(etplId)
    res.Data.EtplId = etplId
    return res, err
}
func (s *server) ListTpl(ctx context.Context, in *svcExport.WshExportTaskListTplReq) (*svcExport.WshExportTaskListTplRes, error) {
    res := new(svcExport.WshExportTaskListTplRes)
    entList, err := model.ListTpl(in.EtplId, in.EtplName, in.EtplTag)
    if err != nil {
        res.ErrMsg = err.Error()
        res.ErrCode = "2"
    }
    for _, ent := range entList {
        t := new(svcExport.WshExportTpl)
        ent.CopyToPb(t)
        res.Data = append(res.Data, t)
    }
    return res, err
}

服務端main啟動服務main.go

/**
 * exporttask server main
 * $ go build exporttask.go
 */
package main
import (
    "log"
    "net"
    svcExport "../../common/exporttask"
    //"./model"
    _ "github.com/go-sql-driver/mysql"
    //"golang.org/x/net/context"
    "google.golang.org/grpc"
    "google.golang.org/grpc/reflection"
)
const (
    port = ":50051"
)
func main() {
    lis, err := net.Listen("tcp", port)
    if err != nil {
        log.Fatalf("failed to listen: %v", err)
    }
    // 生成一個rpc伺服器
    s := grpc.NewServer()
    // 使用pb包呼叫註冊已實現的rpc介面類server
    svcExport.RegisterExportTaskServer(s, &server{})
    // Register reflection service on gRPC server.
    reflection.Register(s)
    if err := s.Serve(lis); err != nil {
        log.Fatalf("failed to serve: %v", err)
    }
}

Golang gRPC客戶端

客戶端的程式碼相對比較簡單

package main
import (
    "flag"
    "log"
    "os"
    svcExport "../../common/exporttask"
    "golang.org/x/net/context"
    "google.golang.org/grpc"
)
const (
    address     = "127.0.0.1:50052"
    defaultName = "world"
)
func main() {
    // 發起連結
    conn, err := grpc.Dial(address, grpc.WithInsecure())
    if err != nil {
        log.Fatalf("did not connect: %v", err)
    }
    defer conn.Close()
    // 建立pb包的客戶端
    c := svcExport.NewExportTaskClient(conn)
    name := defaultName
    if len(os.Args) > 1 {
        name = os.Args[1]
    }
    // 發起請求
    var r2 *svcExport.WshExportTaskCreateTplRes
    req := svcExport.WshExportTaskCreateTplReq{EtplName: name, EtplTag: "mall", EtplExpr: "select EtplName from welife_export_tpl", EtplOutputFormat: svcExport.WshExportFormat_FMT_CSV, EtplOutputColumns: ""}
    r2, err = c.CreateTpl(context.Background(), &req)
    // 列印結果
    log.Println("create tpl: r=", r2, err)
}

gRPC有四種通訊方式

1、 Simple RPC

簡單rpc

這就是一般的rpc呼叫,一個請求物件對應一個返回物件

proto語法:

rpc simpleHello(Person) returns (Result) {}

2、 Server-side streaming RPC

服務端流式rpc

一個請求物件,服務端可以傳回多個結果物件

proto語法

rpc serverStreamHello(Person) returns (stream Result) {}

3、 Client-side streaming RPC

客戶端流式rpc

客戶端傳入多個請求物件,服務端返回一個響應結果

proto語法

rpc clientStreamHello(stream Person) returns (Result) {}

4、 Bidirectional streaming RPC

雙向流式rpc

結合客戶端流式rpc和服務端流式rpc,可以傳入多個物件,返回多個響應物件

proto語法

rpc biStreamHello(stream Person) returns (stream Result) {}