grpc基於golang的客戶端服務端整體預覽
阿新 • • 發佈:2019-02-08
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
}