GRPC框架入门

文章介绍了GRPC协议,它基于http2,支持二进制流和流式传输,提高了效率。ProtoBuf用于定义语言无关的数据结构,通过protoc编译生成跨平台的代码。文中展示了如何创建ProtoBuf定义文件并使用Go进行编码和解码操作,同时也提及了复合类型和枚举类型的使用。
摘要由CSDN通过智能技术生成

背景知识

API服务

前端发送请求时,需要和后端确定协议、服务器地址、路径、参数、数据类型(json,XML,二进制流)、数据编码、安全性(那里存放token)、错误处理等。

GRPC

  1. 协议:http2
    1. http2与 http1 具有相同的方法、header、body。
    2. http2采用二进制传输数据。
    3. http2采用流式传输,传统的传输是服务器生成所有的数据之后才传输回来,而流式传输生成多少传输多少。
    4. http2采用多路复用,而多路复用可以多个请求共用一个连接,而http1也可以共用,但是必须要前一个请求回来再发送下一个。http2不需要。
  2. 方法:post
  3. 路径:/service/method
  4. 参数:body
  5. 安全行:http2+token放在header里
  6. 数据:二进制流
  7. 数据结构:ProtoBuf

优点

高效数据传输,语言无关的领域模型定义。

ProtoBuf

ProtoBuf的使用

创建trip.proto文件

//trip.proto
syntax = "proto3";
package coolcar ;  
//                  生成的路径         生成的包名
option go_package = "coolcar/proto/gen/go;trippb";

message Trip{
    string start = 1;
    string end = 2;
    int64 duration_sec = 3;
    int64 fee_cnet = 4;
}

通过命令

protoc -I=D:\GoCode\coolcar\server\proto --go_out=paths=source_relative:gen/go trip.proto

编译生成trip.pb.go文件(部分代码)

// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// 	protoc-gen-go v1.31.0
// 	protoc        v3.13.0
// source: trip.proto

package trippb

import (
	protoreflect "google.golang.org/protobuf/reflect/protoreflect"
	protoimpl "google.golang.org/protobuf/runtime/protoimpl"
	reflect "reflect"
	sync "sync"
)

const (
	// Verify that this generated code is sufficiently up-to-date.
	_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
	// Verify that runtime/protoimpl is sufficiently up-to-date.
	_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
)

type Trip struct {
	state         protoimpl.MessageState
	sizeCache     protoimpl.SizeCache
	unknownFields protoimpl.UnknownFields
	
	//下划线的变量名,编译成驼峰形式
	Start       string `protobuf:"bytes,1,opt,name=start,proto3" json:"start,omitempty"`
	End         string `protobuf:"bytes,2,opt,name=end,proto3" json:"end,omitempty"`
	DurationSec int64  `protobuf:"varint,3,opt,name=duration_sec,json=durationSec,proto3" json:"duration_sec,omitempty"`
	FeeCnet     int64  `protobuf:"varint,4,opt,name=fee_cnet,json=feeCnet,proto3" json:"fee_cnet,omitempty"`
}

在main.go中使用trip.pb.go

//main.go
package main

import (
	trippb "coolcar/proto/gen/go"
	"encoding/json"
	"fmt"

	"google.golang.org/protobuf/proto"
)

func main() {
	trip:=trippb.Trip{
		Start: "abc",
		End: "def",
		DurationSec: 1000,
		FeeCnet: 1000,
	}
	//trip中的锁等值无法复制,所以传入地址值
	fmt.Println(&trip)

	//编码trip为二进制
	b,err:=proto.Marshal(&trip)
	if err!=nil{
		panic(err)
	}
	fmt.Printf("%x",b)

	//解码二进制到trip
	var trip2 trippb.Trip
	err=proto.Unmarshal(b,&trip2)
	if err != nil {
		panic(err)
	}
	fmt.Println(&trip2)

	//trip编码为json
	b,err=json.Marshal(&trip2) 
	if err != nil {
		panic(err)
	}
	fmt.Printf("%s",b)
}

复合类型和枚举类型

message Location {
    double latitude = 1;
    double longtitue = 2;
}

//枚举类型
enum TripStatus {
    TS_NOT_SPECIFIED = 0;
    NOT_START = 1;
    IN_PROGRESS = 2;
    FINISHED = 3;
    PAID = 4;
}

message Trip{
    string start = 1;
    string end = 2;
    int64 duration_sec = 3;
    int64 fee_cnet = 4;
		//复合类型
    Location start_pos = 5;
    Location end_pos = 6;
		//切片类型
    repeated Location path_locations = 7;
}

初始化复合类型

trip:=trippb.Trip{
		Start: "abc",
		End: "def",
		DurationSec: 1000,
		FeeCnet: 1000,
		EndPos: &trippb.Location{
			Latitude:100,
			Longtitue:100,
		},
		//使用指针来赋值
		StartPos: &trippb.Location{
			Latitude:100,
			Longtitue:100,
		},
		PathLocations: []*trippb.Location{
           {
			Latitude:100,
			Longtitue:100,
		   },
		   {
			Latitude:100,
			Longtitue:100,
		   },
		},
		//枚举形式的赋值
		Status: trippb.TripStatus_FINISHED,
	}

protobuf字段的可选性

任何字段都可以不指定,默认为零值。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值
>