欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Golang安裝和使用protocol-buffer流程介紹

 更新時(shí)間:2022年09月14日 09:14:50   作者:whynogome  
這篇文章主要介紹了Golang安裝和使用protocol-buffer過(guò)程,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧

前言

protocol buffer是Google發(fā)布的一種獨(dú)立的數(shù)據(jù)交換格式,類(lèi)似于json,用于數(shù)據(jù)的序列化和解析。不同點(diǎn)是不能直接在各編程語(yǔ)言中使用,需要先在一個(gè)proto文件中定義需要傳輸?shù)臄?shù)據(jù)格式,然后使用proto工具把proto文件編譯成想要的語(yǔ)言,如java、go、php等。然后在代碼中,使用語(yǔ)言對(duì)應(yīng)的protocol buffer包調(diào)用proto工具生成的文件,完成數(shù)據(jù)的序列化

安裝protoc編譯工具

首先安裝protoc編譯工具,在http://github.com/google/protobuf/releases,根據(jù)自己的系統(tǒng)選擇包,下載后解壓。我是win10 64,所以選擇protoc-21.4-win64.zip,解壓后放在了E盤(pán)。

添加環(huán)境變量,讓系統(tǒng)命令可以識(shí)別protoc命令。

配置環(huán)境變量

PB_PATH=E:\protoc-3.21.4-win64

PATH=%PB_PATH%\bin

添加后,在命令行執(zhí)行 protoc,返回信息,表示安裝成功

編寫(xiě)proto文件

創(chuàng)建一個(gè)user.proto文件,該文件下可以定義一些user相關(guān)的需要加密的字段

//引入其他proto文件,就可以使用該文件中定義的message類(lèi)型,定義本文件中的message下的字段
import "myproject/other_protos.proto";
// 指定的當(dāng)前proto語(yǔ)法的版本
syntax = "proto3";
// 指定生成出來(lái)的文件的package,用來(lái)避免同一個(gè)文件調(diào)同名的消息時(shí)沖突
// 包說(shuō)明符對(duì)生成代碼的影響取決于您選擇的語(yǔ)言,php會(huì)生成命名空間,go會(huì)生成package
package service;
//根據(jù)編程語(yǔ)言不同,參數(shù)名不同
//下面代碼指定了生成go文件的生成目錄,文件的包名。不設(shè)置包名時(shí),包名默認(rèn)為go文件所在目錄名。會(huì)覆蓋package設(shè)置的go的包名
//路徑以執(zhí)行命令的目錄為當(dāng)前目錄,尋找相對(duì)路徑
option go_package="./;service";
//定義消息類(lèi)型,通過(guò)關(guān)鍵字message字段指定的,消息就是需要傳輸?shù)臄?shù)據(jù)格式的定義
message User {
// required必傳;optional 可選;repeated 可重復(fù)初入。不寫(xiě)前綴默認(rèn)為required
// 字段名后的數(shù)字不是默認(rèn)值,是標(biāo)識(shí)。標(biāo)識(shí)號(hào)是[0,2^29-1]范圍內(nèi)的一個(gè)整數(shù)。[1-15]內(nèi)的標(biāo)識(shí)號(hào)在編碼時(shí)只占用一個(gè)字節(jié),包含標(biāo)識(shí)符和字段類(lèi)型,[16-2047]之間的標(biāo)識(shí)符占用2個(gè)字節(jié)。建議為頻繁出現(xiàn)的字段使用[1-15]間的標(biāo)識(shí)符。
//字段類(lèi)型除了除了常規(guī)類(lèi)型,也可使用import引入文件中定義的message類(lèi)型
	required string sername = 1;
	optional int32 age = 2;
	repeated int32 height = 3;
}
//定義服務(wù)類(lèi)型,用作rpc通訊
service SearchService {
    //rpc 服務(wù)的函數(shù)名 (傳入?yún)?shù))返回(返回參數(shù))
    //傳入和返回參數(shù),需要使用proto中定義的message
    rpc Search (SearchRequest) returns (SearchResponse);
}

生成指定語(yǔ)言的proto文件

protoc內(nèi)置9中語(yǔ)言的編譯插件,如下

我們以go為例。protoc沒(méi)有內(nèi)置go的編譯器,需要引入外部插件protoc-gen-go

我們使用命令

go get github.com/golang/protobuf/protoc-gen-go

下載并編譯了包,包中有main.go文件,所以在GOPATH/bin目錄下生成了可執(zhí)行文件protoc-gen-go.exe,這個(gè)文件就是我們?cè)趐rotoc中用到的插件

我們也可以自定義自己的插件。插件名必須以protoc-gen-插件名.exe命名

在調(diào)用時(shí)以:插件_out=參數(shù) 調(diào)用,之后回講到如何制作插件

我們以go_out插件為例,執(zhí)行命令

命令行后的第一個(gè)參數(shù)為輸出目錄。但是我們已經(jīng)在go_package中指定了目錄,所以第一個(gè)參數(shù)是無(wú)效的,填當(dāng)前目錄.即可。第二個(gè)參數(shù)是,要編譯的文件路徑和文件名(以命令執(zhí)行目錄為當(dāng)前目錄的相對(duì)路徑)

protoc后可以追加1個(gè)或多個(gè) -I=path 指定解析import指令時(shí)要在其中查找.proto文件的目錄,若文件沒(méi)有使用import,則不需要該參數(shù)

protoc --go_out=. proto_type/hello.proto

報(bào)錯(cuò)

protoc默認(rèn)會(huì)從環(huán)境變量path下的路徑中尋找插件,沒(méi)找到報(bào)錯(cuò)。

查看發(fā)現(xiàn)path中只配置了go的安裝GOROOT目錄下的bin,而protoc-gen-go.exe在GOPATH的bin目錄下

我們把protoc-gen-go.exe復(fù)制到GOROOT的bin目錄下,即可?;蛘咴诃h(huán)境變量path中添加gopath/bin目錄。再次執(zhí)行命令即可

調(diào)用proto

import (
	"fmt"
	"github.com/golang/protobuf/proto"
)
func main() {
	//定義一個(gè)要加密的變量
	msg := &protoc_type.User{
		Username:"zhangsan",
		Age:12,
	}
	//加密
	marshal,err := proto.Marshal(msg)
	if err!=nil{
		fmt.Println(err.Error())
	}else{
		fmt.Println(marshal)
	}
	//定義一個(gè)變量,用于接收解碼的值,類(lèi)型必須用加密的值類(lèi)型一樣
	unmarshal := &protoc_type.User{}
	//解碼
	err2 := proto.Unmarshal(marshal,unmarshal)
	if err2 == nil{
		fmt.Println(unmarshal)
		fmt.Println(unmarshal.Username)
		fmt.Printf("%T",unmarshal)
	}
}	

制作插件

我們上文中提到,生成go用到了一個(gè)protoc的外部插件。插件的工作原理其實(shí)就是讀取proto文件內(nèi)容,并根據(jù)文件內(nèi)容生成指定文件。文件中保存了定義的字段類(lèi)型和方法之間的關(guān)系,以便編碼和解碼時(shí)使用

當(dāng)我們?cè)趐roto文件中定義了service,說(shuō)明我們需要用到rpc服務(wù)。protoc內(nèi)置的插件和一些官方的外部插件,只是提供了service中方法與參數(shù)類(lèi)型的綁定,用于校驗(yàn)調(diào)用方法時(shí)類(lèi)型是否正確。在service中定義的方法,我們需要自己創(chuàng)建。

當(dāng)方法較多時(shí),我們需要打開(kāi)proto文件,一一對(duì)應(yīng)的創(chuàng)建func,效率不高也容易出錯(cuò)。這種情況下,我們制作一個(gè)插件,讀取service內(nèi)容,自動(dòng)創(chuàng)建方法,方法內(nèi)的代碼之后根據(jù)業(yè)務(wù)需求填充即可。

go官方提供了一個(gè)包,可以自動(dòng)解析讀取命令行傳入proto文件,代碼如下

package main
import (
	"fmt"
	"strings"
	"google.golang.org/protobuf/compiler/protogen"
)
type rpc struct{}
func main() {
	g := rpc{}
	protogen.Options{}.Run(g.Generate)
}
// Generate generate service code
func (md *rpc) Generate(plugin *protogen.Plugin) error {
	//遍歷讀取的命令行中傳入的proto文件
	for _, f := range plugin.Files {
		//如果文件中沒(méi)有定義service,跳過(guò)
		if len(f.Services) == 0 {
			continue
		}
		//根據(jù)proto文件名,生成一個(gè)自定義的文件,保存該proto中定義的func
		fileName := f.GeneratedFilenamePrefix + ".svr.go"
		//把該文件保存在proto文件的所在目錄
		t := plugin.NewGeneratedFile(fileName, f.GoImportPath)
		//寫(xiě)入文字
		t.P("http:// Code generated by protoc-gen-tinyrpc.")
		//寫(xiě)入空行
		t.P()
		//寫(xiě)入包名
		pkg := fmt.Sprintf("package %s", f.GoPackageName)
		t.P(pkg)
		t.P()
		//遍歷一個(gè)文件下所有service,自動(dòng)生成方法
		for _, s := range f.Services {
			//插入注釋?zhuān)xservice類(lèi)型
			serviceCode := fmt.Sprintf(`%stype %s struct{}`,
				getComments(s.Comments), s.Desc.Name())
			t.P(serviceCode)
			t.P()
			//遍歷一個(gè)service下的方法,生成方法
			for _, m := range s.Methods {
				funcCode := fmt.Sprintf(`%sfunc(this *%s) %s(args *%s,reply *%s)error{
					// define your service ...
					return nil
				}
				`, getComments(m.Comments), s.Desc.Name(),
					m.Desc.Name(), m.Input.Desc.Name(), m.Output.Desc.Name())
				t.P(funcCode)
			}
		}
	}
	return nil
}
// getComments get comment details
func getComments(comments protogen.CommentSet) string {
	c := make([]string, 0)
	c = append(c, strings.Split(string(comments.Leading), "\n")...)
	c = append(c, strings.Split(string(comments.Trailing), "\n")...)
	res := ""
	for _, comment := range c {
		if strings.TrimSpace(comment) == "" {
			continue
		}
		res += "http://" + comment + "\n"
	}
	return res
}

執(zhí)行 go install 編譯該文件,生成exe文件,文件名稱(chēng)設(shè)置為protoc-gen-gofunc.exe。然后再次執(zhí)行protoc命令,如下

protoc --go_out=. proto_type/hello.proto --gofunc_out=. proto_type/hello.proto

執(zhí)行后,會(huì)在proto_type目錄下生成兩個(gè)文件,hello.pd.go, hello.srv.go

到此這篇關(guān)于Golang安裝和使用protocol-buffer方法介紹的文章就介紹到這了,更多相關(guān)Golang protocol-buffer內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Golang實(shí)現(xiàn)Md5校驗(yàn)的示例代碼

    Golang實(shí)現(xiàn)Md5校驗(yàn)的示例代碼

    本文主要介紹了Golang實(shí)現(xiàn)Md5校驗(yàn)的示例代碼,要求接收方需要文件的md5值,和接收到的文件做比對(duì),以免文件不完整,但引起bug,下面就一起來(lái)解決一下
    2024-08-08
  • GO語(yǔ)言并發(fā)之好用的sync包詳解

    GO語(yǔ)言并發(fā)之好用的sync包詳解

    標(biāo)準(zhǔn)庫(kù)中的sync包在我們的日常開(kāi)發(fā)中用的頗為廣泛,那么大家對(duì)sync包的用法知道多少呢,這篇文章就大致講一下sync包和它的使用,感興趣的可以學(xué)習(xí)一下
    2022-12-12
  • Go?語(yǔ)言?json解析框架與?gjson?詳解

    Go?語(yǔ)言?json解析框架與?gjson?詳解

    這篇文章主要介紹了Go語(yǔ)言json解析框架與gjson,JSON?解析是我們不可避免的常見(jiàn)問(wèn)題,在Go語(yǔ)言中,我們可以借助gjson庫(kù)來(lái)方便的進(jìn)行json屬性的提取與解析,需要的朋友可以參考一下
    2022-07-07
  • 圖解Golang的GC垃圾回收算法

    圖解Golang的GC垃圾回收算法

    這篇文章主要介紹了圖解Golang的GC垃圾回收算法,詳細(xì)的介紹了三種經(jīng)典的算法,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2019-03-03
  • Golang?WaitGroup?底層原理及源碼解析

    Golang?WaitGroup?底層原理及源碼解析

    WaitGroup?是?Golang?中最常見(jiàn)的并發(fā)控制技術(shù)之一,它的作用我們可以簡(jiǎn)單類(lèi)比為其他語(yǔ)言中多線程并發(fā)控制中的?join(),這篇文章主要介紹了Golang?WaitGroup?底層原理及源碼詳解,需要的朋友可以參考下
    2023-04-04
  • Go語(yǔ)言hello world實(shí)例

    Go語(yǔ)言hello world實(shí)例

    這篇文章主要介紹了Go語(yǔ)言hello world實(shí)例,本文先是給出了hello world的代碼實(shí)例,然后對(duì)一些知識(shí)點(diǎn)和技巧做了解釋,需要的朋友可以參考下
    2014-10-10
  • go語(yǔ)言中值類(lèi)型和指針類(lèi)型的深入理解

    go語(yǔ)言中值類(lèi)型和指針類(lèi)型的深入理解

    這篇文章主要給大家介紹了關(guān)于go語(yǔ)言中值類(lèi)型和指針類(lèi)型的相關(guān)資料,文中通過(guò)實(shí)例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2022-03-03
  • golang qq郵件發(fā)送驗(yàn)證碼功能

    golang qq郵件發(fā)送驗(yàn)證碼功能

    驗(yàn)證碼在多個(gè)場(chǎng)景下發(fā)揮著重要作用,如注冊(cè)/登錄、短信接口保護(hù)、提交/投票、密碼找回和支付驗(yàn)證等,以保障賬號(hào)安全和防止惡意操作,此外,文章還介紹了使用golang通過(guò)qq郵件發(fā)送驗(yàn)證碼的實(shí)現(xiàn)過(guò)程,包括獲取授權(quán)碼、下載依賴(lài)包和編寫(xiě)代碼,感興趣的朋友跟隨小編一起看看吧
    2024-09-09
  • Go語(yǔ)言設(shè)計(jì)模式之結(jié)構(gòu)型模式

    Go語(yǔ)言設(shè)計(jì)模式之結(jié)構(gòu)型模式

    本文主要聚焦在結(jié)構(gòu)型模式(Structural Pattern)上,其主要思想是將多個(gè)對(duì)象組裝成較大的結(jié)構(gòu),并同時(shí)保持結(jié)構(gòu)的靈活和高效,從程序的結(jié)構(gòu)上解決模塊之間的耦合問(wèn)題
    2021-06-06
  • gin框架Context如何獲取Get?Query?Param函數(shù)數(shù)據(jù)

    gin框架Context如何獲取Get?Query?Param函數(shù)數(shù)據(jù)

    這篇文章主要為大家介紹了gin框架Context?Get?Query?Param函數(shù)獲取數(shù)據(jù),有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-03-03

最新評(píng)論