grpc之protobuf常用語法速學


1,語法速學(1):返回商品”數組”、repeated修飾符

Repeated:是一個修飾符,返回字段可以重復任意多次(包括0次) 可以認為就是一個數組(切片)

 

服務端:

創建protobuf文件

syntax="proto3";
package services;
import "google/api/annotations.proto";

message  ProdRequest {
    int32 prod_id =1;   //傳入的商品ID
}
message ProdResponse{
    int32 prod_stock=1;//商品庫存
}

message QuerySize{
    int32 size = 1;//頁尺寸
}

//返回 一堆商品庫存,使用了repeated修飾符
message ProdResponseList{
    repeated ProdResponse prodres=1;
}

service ProdService {
    rpc GetProdStock (ProdRequest) returns (ProdResponse){
        option (google.api.http) = {
            get: "/v1/prod/{prod_id}"
        };

    }
    rpc GetProdStocks(QuerySize) returns (ProdResponseList){

    }
}

 

生成Prod.pb.go文件

cd pbfiles && protoc --go_out=plugins=grpc:../services  Prod.proto

 

創建ProdSerbice.go文件

package services

import (
    "context"
)

type ProdService struct {

}

func(this *ProdService) GetProdStock(ctx context.Context, request *ProdRequest) (*ProdResponse, error) {

      return &ProdResponse{ProdStock:20},nil
}

func (this *ProdService) GetProdStocks(ctx context.Context,size *QuerySize) (*ProdResponseList, error){
    var Prodres []*ProdResponse
    Prodres = make([]*ProdResponse,0,3)
    Prodres = append(Prodres,&ProdResponse{ProdStock:28,})
    Prodres = append(Prodres,&ProdResponse{ProdStock:29,})
    Prodres = append(Prodres,&ProdResponse{ProdStock:30,})
    return &ProdResponseList{
        Prodres:Prodres,
    },nil
}

 

server.go

package main

import (
    "google.golang.org/grpc"
    "grpcpro/services"
    "net"
)

func main()  {
    rpcServer:=grpc.NewServer()
    services.RegisterProdServiceServer(rpcServer,new(services.ProdService))

    lis,_:=net.Listen("tcp",":8081")

    rpcServer.Serve(lis)


}

啟動服務

go run server.go

 

客戶端:

拷貝服務端的生成的文件Prod.pb.go到客戶端目錄下

mian.go

package main

import (
    "context"
    "fmt"
    "google.golang.org/grpc"
    "gprccli/services"
    "log"
)

func main(){

    conn,err:=grpc.Dial(":8081",grpc.WithInsecure())
    if err!=nil{
        log.Fatal(err)
    }
    defer conn.Close()

    prodClient:=services.NewProdServiceClient(conn)
    ctx:=context.Background()

    //prodRes,err:=prodClient.GetProdStock(context.Background(),
    //    &services.ProdRequest{ProdId:12})
    //if err!=nil{
    //    log.Fatal(err)
    //}
    //fmt.Println(prodRes.ProdStock)

    response,err := prodClient.GetProdStocks(ctx,&services.QuerySize{Size:10})

    if err!=nil{
        log.Fatal(err)
    }
    fmt.Println(response.Prodres[2].ProdStock)
}

啟動客戶端client 調用服務端gprc服務

go run main.go

 

2,語法速學(2): 使用枚舉、獲取分區商品庫存

  1、傳入一個商品ID 獲取一個商品庫存。

  2、根據size獲取一堆商品的庫存列表

  3,創建枚舉類型,支持分區枚舉參數

enum ProdAreas{
    A=0;
    B=1;
    C=2;
}

ProdService.go

package services

import (
    "context"
)

type ProdService struct {}

func(this *ProdService) GetProdStock(ctx context.Context, request *ProdRequest) (*ProdResponse, error) {

      var stock int32=0
      if request.ProdArea==ProdAreas_A{
          stock=30
      }else if request.ProdArea==ProdAreas_B{
          stock=31
      }else{
          stock=50
      }
      return &ProdResponse{ProdStock:stock},nil
}
func(this *ProdService) GetProdStocks(ctx context.Context,size *QuerySize) (*ProdResponseList, error)  {
            Prodres:= []*ProdResponse{
                    &ProdResponse{ProdStock:28},
                    &ProdResponse{ProdStock:29},
                    &ProdResponse{ProdStock:30},
                    &ProdResponse{ProdStock:31},
            }
            return &ProdResponseList{
                Prodres:Prodres,
            },nil
}

 

語法速學(3): 導入外部Proto、獲取商品信息

 

服務端:

Models.proto

syntax="proto3";
package services;
message ProdModel{ //商品模型
    int32 prod_id=1;
    string prod_name=2;
    float prod_price=3;
}

 

Prod.proto

syntax="proto3";
package services;


import "google/api/annotations.proto";
import "Models.proto";

enum ProdAreas{
    A=0;
    B=1;
    C=2;
}

message  ProdRequest {
    int32 prod_id =1;   //傳入的商品ID
}
message ProdResponse{
    int32 prod_stock=1;//商品庫存
}

message QuerySize{
    int32 size = 1;//頁尺寸
}

//返回 一堆商品庫存,使用了repeated修飾符
message ProdResponseList{
    repeated ProdResponse prodres=1;
}

service ProdService {
    rpc GetProdStock (ProdRequest) returns (ProdResponse){
        option (google.api.http) = {
            get: "/v1/prod/{prod_id}"
        };

    }
    rpc GetProdStocks(QuerySize) returns (ProdResponseList){

    }

    rpc GetProdInfo(ProdRequest) returns(ProdModel){}
}

 

生成pb.go文件

protoc --go_out=plugins=grpc:../services  Prod.proto

protoc --go_out=plugins=grpc:../services  Models.proto

 

ProdService.go

package services

import (
    "context"
)

type ProdService struct {

}

func(this *ProdService) GetProdStock(ctx context.Context, request *ProdRequest) (*ProdResponse, error) {

      return &ProdResponse{ProdStock:20},nil
}

func (this *ProdService) GetProdStocks(ctx context.Context,size *QuerySize) (*ProdResponseList, error){
    var Prodres []*ProdResponse
    Prodres = make([]*ProdResponse,0,3)
    Prodres = append(Prodres,&ProdResponse{ProdStock:28,})
    Prodres = append(Prodres,&ProdResponse{ProdStock:29,})
    Prodres = append(Prodres,&ProdResponse{ProdStock:30,})
    return &ProdResponseList{
        Prodres:Prodres,
    },nil
}

func (this *ProdService) GetProdInfo(ctx context.Context, in *ProdRequest) (*ProdModel, error){

    ret:=ProdModel{
        ProdId:101,
        ProdName:"測試商品",
        ProdPrice:20.5,
    }
    return &ret,nil
}

 

 

客戶端:

拷貝服務端 Models.pb.go和Prod.pb.go到客戶端下

package main

import (
    "context"
    "fmt"
    "google.golang.org/grpc"
    "gprccli/services"
    "log"
)

func main(){

    conn,err:=grpc.Dial(":8081",grpc.WithInsecure())
    if err!=nil{
        log.Fatal(err)
    }
    defer conn.Close()

    prodClient:=services.NewProdServiceClient(conn)
    ctx:=context.Background()

    //prodRes,err:=prodClient.GetProdStock(context.Background(),
    //    &services.ProdRequest{ProdId:12})
    //if err!=nil{
    //    log.Fatal(err)
    //}
    //fmt.Println(prodRes.ProdStock)

    //response,err := prodClient.GetProdStocks(ctx,&services.QuerySize{Size:10})
    //
    //if err!=nil{
    //    log.Fatal(err)
    //}
    //fmt.Println(response.Prodres[2].ProdStock)

    prod,err :=prodClient.GetProdInfo(ctx,&services.ProdRequest{ProdId:12})
    if err!=nil{
        log.Fatal(err)
    }
    fmt.Println(prod)
}

 

語法學習日期類型、創建主訂單模型(下)

服務端:

Models.proto

syntax="proto3";
package services;

import "google/protobuf/timestamp.proto";

message ProdModel{ //商品模型
    int32 prod_id=1;
    string prod_name=2;
    float prod_price=3;
}


message OrderMain{ //主訂單模型
      int32 order_id=1;//訂單ID,數字自增
      string order_no=2; //訂單號
      int32 user_id=3; //購買者ID
      float order_money=4;//商品金額
      google.protobuf.Timestamp order_time=5; //下單時間
}

 

Orders.proto

syntax="proto3";
package services;

import "Models.proto";

message OrderResponse{
    string status=1;
    string message=2;
}
service OrderSerivce{
    rpc NewOrder(OrderMain) returns (OrderResponse){}
}

 

$ protoc --go_out=plugins=grpc:../services Models.proto

$ protoc --go_out=plugins=grpc:../services Orders.proto

生成pb.go文件

 

OrdersService.go

package services

import (
    "context"
    "fmt"
)

type OrdersService struct {

}

func(this *OrdersService)NewOrder(ctx context.Context,orderMain *OrderMain) (*OrderResponse, error)   {
    fmt.Println(orderMain)
    return &OrderResponse{
        Status:"OK",
        Message:"success",
    },nil
}

 

server.go

func main()  {
    rpcServer:=grpc.NewServer()
    services.RegisterProdServiceServer(rpcServer,new(services.ProdService))
    services.RegisterOrderSerivceServer(rpcServer,new(services.OrdersService))

    lis,_:=net.Listen("tcp",":8081")

    rpcServer.Serve(lis)


}

 

客戶端:

首先拷貝Orders.pb.go和Models.pb.go到客戶端

package main

import (
    "context"
    "fmt"
    "github.com/golang/protobuf/ptypes/timestamp"
    "google.golang.org/grpc"
    "gprccli/services"
    "log"
    "time"
)

func main2(){

    conn,err:=grpc.Dial(":8081",grpc.WithInsecure())
    if err!=nil{
        log.Fatal(err)
    }
    defer conn.Close()

    prodClient:=services.NewProdServiceClient(conn)
    ctx:=context.Background()

    //prodRes,err:=prodClient.GetProdStock(context.Background(),
    //    &services.ProdRequest{ProdId:12})
    //if err!=nil{
    //    log.Fatal(err)
    //}
    //fmt.Println(prodRes.ProdStock)

    //response,err := prodClient.GetProdStocks(ctx,&services.QuerySize{Size:10})
    //
    //if err!=nil{
    //    log.Fatal(err)
    //}
    //fmt.Println(response.Prodres[2].ProdStock)

    prod,err :=prodClient.GetProdInfo(ctx,&services.ProdRequest{ProdId:12})
    if err!=nil{
        log.Fatal(err)
    }
    fmt.Println(prod)
}

func main(){
    conn,err:=grpc.Dial(":8081",grpc.WithInsecure())
    if err!=nil{
        log.Fatal(err)
    }
    defer conn.Close()
    ctx:=context.Background()
    t:=timestamp.Timestamp{Seconds:time.Now().Unix()}
    orderClient:=services.NewOrderSerivceClient(conn)
    res,_:= orderClient.NewOrder(ctx,&services.OrderMain{
        OrderId:1001,
        OrderNo:"20190809",
        OrderMoney:90,
        OrderTime:&t,
    })
    fmt.Println(res)
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM