1. 程式人生 > >grpc基於golang的客戶端服務端整體預覽

grpc基於golang的客戶端服務端整體預覽

proto檔案:

/*
* @Title: 服務介面說明
* @Description: 介面目錄
*/
service SpotDataHandler {
    rpc GetProductInfo(GetProductInfoRequest) returns (GetProductInfoResponse) {}//獲取所有商品資訊
}

/**
* @Title: 統一說明
* @Description: 通用message定義

message SpotPriceInfo {
    double high = 2;//當日最高
    double low = 3;//當日最低
    double average = 4;//當日平均
    double vchange = 5;//當日漲跌
    double vchange_rate = 6;//當日漲跌幅
    int32 price_state = 7;//價格狀態,0正常,1缺貨,2休盤
    string renew_date = 8;//更新日期,YYYY-MM-DD格式
    string renew_time = 9;//更新時間,HH:MM:SS格式
    string price_declaration = 10;//價格說明
}

message PriceType {
    oneof TypeEnum {
        SpotPriceInfo spot_price = 1;//現貨
    }
}

message PriceInfo {
    string product_id = 1;//產品id
    string product_name = 2;//產品名稱
    string unit = 3;//單位
    repeated PriceType price_list = 4;
}

/**
* @Title
: 1.獲取所有分類資訊 * @Description: * @Request: GetProductInfoRequest * @Response: GetProductInfoResponse */
message GetProductInfoRequest { string language = 1;//cn中文,en英文 } message ProductInfo { string product_id = 1;//產品id string product_name = 2;//產品名稱 string spec = 3;//產品規格 string brand_mark = 4
;//品牌 string area = 5;//地區 string unit = 6;//單位 } message GetProductInfoResponse { message CategoryInfo { int32 category_id = 1;//屬性id,唯一 string category_name = 2;//屬性名稱 int32 list_order = 3;//排序id repeated ProductInfo products = 4;//商品列表 } message ItemInfo { int32 item_id = 1
;//品目id,唯一 string item_name = 2;//品目名稱 int32 list_order = 3;//排序id repeated CategoryInfo categories = 4; } MessageProto codeMsg = 1; repeated ItemInfo items = 2; }

然後由這個proto檔案生成對應的pb.go:

.
.
.
type SpotDataHandlerServer interface {
    GetProductInfo(context.Context, *GetProductInfoRequest) (*GetProductInfoResponse, error)
}
.
.
.

服務端:

//實現pb.go中interface定義的方法
func (s *SpotDataHandler) GetProductInfo(c context.Context, req *spot.GetProductInfoRequest) (*spot.GetProductInfoResponse, error) {
    // check param
    switch strings.ToLower(req.Language) {
    case SpotDataHandler_Language_CN:
    case SpotDataHandler_Language_EN:
    default:
        req.Language = SpotDataHandler_Language_CN
    }

    var itemInfoList []*spot.GetProductInfoResponse_ItemInfo
    for _, item := range memory.GetItemListNoLimit() {
        if item.Id <= 0 {
            continue
        }

        var categoryList []*spot.GetProductInfoResponse_CategoryInfo
        for _, tagId := range memory.GetTagIdsByItem(item.Id) {
            relation := memory.GetRealtionByTagId(tagId)
            if relation == nil {
                continue
            }

            cat := memory.GetCategoryTag(relation.CategoryId)
            if cat == nil {
                continue
            }

            var proudctList []*spot.ProductInfo
            for _, productId := range memory.GetProductIdsByTagId(tagId) {
                productDetail := memory.GetProductInfoNoLimit(productId)
                if productDetail == nil {
                    continue
                }

                if productDetail.PriceType > constant.Price_Type_Premium {
                    continue
                }

                name := productDetail.ProductName
                spec := productDetail.Spec
                brand := productDetail.BrandMark
                unit := productDetail.Unit
                area := productDetail.Area

                if strings.ToLower(req.Language) == SpotDataHandler_Language_EN {
                    productDetailEn, err := cache.GRedis[cache.REDIS_EN].CacheGetEnProductDetailByID(productId)
                    if err != nil {
                        productDetailEn, err = db.DBGetEnProductDetailByProductID(productId)
                        if err != nil {
                            logger.Warnning(err)
                            continue
                        }

                        go command.LoadEnProducts(constant.PROGRAM_ENV_EN)
                    }

                    name = productDetailEn.ProductName
                    spec = productDetailEn.Spec
                    brand = ""
                    unit = productDetailEn.Unit
                    area = ""
                }

                proudctList = append(proudctList, &spot.ProductInfo{
                    ProductId:   productId,
                    ProductName: name,
                    Spec:        spec,
                    BrandMark:   brand,
                    Unit:        unit,
                    Area:        area,
                })
            }

            if len(proudctList) == 0 {
                continue
            }

            categoryList = append(categoryList, &spot.GetProductInfoResponse_CategoryInfo{
                CategoryId:   int32(cat.Id),
                CategoryName: cat.CategoryName,
                ListOrder:    int32(cat.ListOrder),
                Products:     proudctList,
            })
        }

        if len(categoryList) == 0 {
            continue
        }

        itemInfoList = append(itemInfoList, &spot.GetProductInfoResponse_ItemInfo{
            ItemId:     int32(item.Id),
            ItemName:   item.ItemName,
            ListOrder:  int32(item.ListOrder),
            Categories: categoryList,
        })
    }

    return &spot.GetProductInfoResponse{
        CodeMsg: &spot.MessageProto{
            Code: protocol.RESPONSE_CODE_SUCCESS,
            Msg:  protocol.RESPONSE_MSG_SUCCESS,
        },
        Items: itemInfoList,
    }, nil
}

客戶端:

func initSpotGRPCConn() {
    // Set up a connection to the server.
    logger.Debug("connect GRPC service", common.GetConfigs().API.SpotCenterGRPC)
    conn, err := grpc.Dial(common.GetConfigs().API.SpotCenterGRPC, grpc.WithInsecure(), grpc.WithReadBufferSize(10*1024*1024), grpc.WithWriteBufferSize(1*1024*1024))
    if err != nil {
        log.Fatalf("did not connect: %v", err)
    }
    DefaultSpotDataConn = conn

    logger.Debug("init spot api")
    DefaultSpotDataClient = spot.NewSpotDataHandlerClient(DefaultSpotDataConn)
}


func getSpotItems(pr *spot.GetProductInfoRequest) ([]*spot.GetProductInfoResponse_ItemInfo, error) {
    con, _ := context.WithTimeout(context.Background(), time.Second*utility.TIME_OUT)
    replay, err := invoke.DefaultSpotDataClient.GetProductInfo(con, pr)
    if err != nil {
        return nil, err
    }
    if replay.CodeMsg == nil {
        return nil, utility.NewError(utility.ERROR_RPC_CODE, utility.ERROR_MSG_RPC_DATA_NULL)
    }
    // success == 0
    if replay.CodeMsg.Code != utility.SMMSPOT_DATABASE_SUCCESS {
        return nil, utility.NewError(utility.ERROR_RPC_CODE, replay.CodeMsg.Msg)
    }
    if replay.Items == nil {
        return nil, utility.NewError(utility.ERROR_RPC_CODE, utility.ERROR_MSG_RPC_DATA_NULL)
    }
    return replay.Items, nil
}