Window环境下使用go编译grpc最新教程

news2024/9/22 13:37:49

网上的grpc教程都或多或少有些老或者有些问题,导致最后执行生成文件时会报很多错。这里给出个人实践出可执行的编译命令与碰到的报错与解决方法。(ps:本文代码按照煎鱼的教程编写:4.2 gRPC Client and Server - 跟煎鱼学 Go (gitbook.io))

最后看了官网,果然只有官网的教程不会太老导致不可用。

  • 项目目录结构
grpc_test
├─client
|   └─main
|      └─client.go
└─proto
|   |─grpc
|   └─search.proto
└─server
    └─main
       └─server.go
  • 下载protoc不做介绍请自行下载

    下载后执行protoc --version

    输出类似以下信息则安装成功,否则卸载重新安装

    libprotoc 25.1
    
  • 下载go编译proto插件

    下面的命令已废弃!不要使用

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

    请使用下面命令!

    go get -u google.golang.org/grpc
    go install google.golang.org/protobuf/cmd/protoc-gen-go
    go install google.golang.org/grpc/cmd/protoc-gen-go-grpc
    

    观察GOPATH目录的bin下有两个文件

    在这里插入图片描述

  • 编写search.proto文件

    syntax = "proto3";
    
    package proto;
    
    service SearchService {
        rpc Search(SearchRequest) returns (SearchResponse) {}
    }
    
    message SearchRequest {
        string request = 1;
    }
    
    message SearchResponse {
        string response = 1;
    }
    
  • 执行编译命令

    $ protoc --go_out=plugins=grpc:. *.proto
    

以上是煎鱼的grpc教程,可能由于版本或者环境导致现在并不能使用了,下面列出我遇到的报错以及如何解决

  • 报错一:插件旧库已废弃,且安装新库命令由于本地go tool版本不匹配安装失败

    执行下面命令报错该库已经废弃

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

    执行下面命令时报错tool的版本不对

    go install google.golang.org/protobuf/cmd/protoc-gen-go
    

    报错信息

    compile: version "go1.20.13" does not match go tool version "go1.21.6"
    

    该报错导致插件下载失败,网上说是升级版本时以前的库没删干净,但是我并没用找到以前的库。所以我全部重新安装了最近的1.22

    • 首先把GOPATH下三个文件夹里文件全部删除

    • 把GOROOT里文件全部删除

    • 去官网重新下载Windows版本的1.22的zip文件解压到我的GOROOT里(ps:安装新版本后本地执行go version可能还是以前的版本,不用担心,这是本地环境的缓存,重启一下再go version就好,就像linux里修改环境文件都要sourse一下才能使用)

      重新执行插件安装命令,执行成功!

  • 报错二:执行编译命令失败

    执行下面编译命令时报错

    $ protoc --go_out=plugins=grpc:. *.proto
    

    报错

    'protoc-gen-go' 不是内部或外部命令,也不是可运行的程序
    或批处理文件。
    --go_out: protoc-gen-go: Plugin failed with status code 1.
    

    原因:该命令不可用或者本地插件环境未配置好

    下面把GOPATH的bin目录下新下载的文件安装到GOROOT下bin中解决!

    在这里插入图片描述

    我本地GOROOT的文件夹是go

    在这里插入图片描述

  • 报错三:输出参数不对

    --proto_path passed empty directory name.  (Use "." for current directory.)
    

    这是proto3后来规定文件中必须要配置go_package参数,在文件中配置加上此参数以解决(protoc 3.10 版本后可能会报此错误)

    syntax = "proto3";
    
    package proto;
    
    option go_package = "/grpc;proto";
    
    service SearchService {
        rpc Search(SearchRequest) returns (SearchResponse) {}
    }
    
    message SearchRequest {
        string request = 1;
    }
    
    message SearchResponse {
        string response = 1;
    }
    

    option go_package = “/grpc;proto”;

    分号前是输出的 .pb.go 文件的路径,路径不存在会自动创建

    分号后是输入的 .pb.go 文件的包名

    最后进入proto目录并执行下面命令,grpc目录下会自动生成编译文件(ps:grpc目录自己创建,不建议生成编译go文件在proto中,因为grpc的缺陷是后面修改proto文件都需要重新编译生成go文件,若proto文件写错了会覆盖原来好的文件。建议生成在别的目录下确认不误后再投入使用)

    另外煎鱼的教程可能版本只能生成一个go文件,代码也不对了。请使用下面命令!

    protoc --go_out=. --go-grpc_out=. search.proto
    
    • 煎鱼的代码可能也是不能用了,我重写了一下,加上timeoutcontext的超时关闭逻辑,测试后可以正常运行

    client.go

    package main
    
    import (
    	"context"
    	"fmt"
    	"log"
    	"time"
    
    	"google.golang.org/grpc"
    	"google.golang.org/grpc/credentials/insecure"
    
    	pb "grpc_test/proto/grpc"
    	proto "grpc_test/proto/grpc"
    )
    
    const address = "127.0.0.1:9001"
    
    func getGrpcConn(address string) (*grpc.ClientConn, *proto.SearchServiceClient, *context.CancelFunc, error) {
    	ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
    	// timeoutcontex用于超时自动关闭
    	// grpc.WithBlock()用于配置gRPC客户端连接阻塞并等待连接建立或失败后再返回
    	// 在需要确保连接就绪后再继续执行后续代码的场景中很有用
    	// grpc现在强制要求设置TLS,withinsurance已经废弃
    	conn, err := grpc.DialContext(ctx, address, grpc.WithBlock(), grpc.WithTransportCredentials(insecure.NewCredentials()))
    	if err != nil {
    		msg := fmt.Sprintf("did not connect to %v error %v", address, err)
    		log.Println(msg)
    	}
    	client := proto.NewSearchServiceClient(conn)
    	return conn, &client, &cancel, err
    }
    
    func main() {
    
    	conn, client, _, _ := getGrpcConn(address)
    	defer conn.Close()
    	// Contact the server and print out its response.
    	ctx, cancel := context.WithTimeout(context.Background(), time.Second)
    	defer cancel()
    	// 使用服务端函数
    	resp, err := (*client).Search(ctx, &pb.SearchRequest{Request: "gRPC"})
    	if err != nil {
    		log.Fatalf("client.Search err: %v", err)
    	}
    
    	log.Printf("resp: %s", resp.GetResponse())
    }
    

    server.go

    package main
    
    import (
    	"context"
    	"fmt"
    	"log"
    	"net"
    
    	"google.golang.org/grpc"
    
    	pb "grpc_test/proto/grpc"
    
    )
    
    type SearchService struct {
    	pb.UnimplementedSearchServiceServer
    }
    
    func (s *SearchService) Search(ctx context.Context, r *pb.SearchRequest) (*pb.SearchResponse, error) {
    	fmt.Println("sever serching")
    	return &pb.SearchResponse{Response: r.GetRequest() + " Server"}, nil
    }
    
    const PORT = "9001"
    
    func main() {
    	// 获取grpc服务端(被调用方)
    	server := grpc.NewServer()
    	// 服务端映射到结构体SearchService{}(注册)
    	pb.RegisterSearchServiceServer(server, &SearchService{})
    	// 建立tcp端口监听
    	lis, err := net.Listen("tcp", ":"+PORT)
    	if err != nil {
    		log.Fatalf("net.Listen err: %v", err)
    	}
    	// 服务端监听tcp连接
    	if err := server.Serve(lis); err != nil {
    		log.Fatalf("net.Listen err: %v", err)
    	}
    }
    

    有兴趣的可以看看rpc的设计原理,其实大多应用在使用时就可以反映出大致原理,rpc的设计框架也是,从网络传输协议,序列化协议,消息编码协议三层设计,另外加上函数注册和参数注册的逻辑。利用tcp或者http建立连接,传输编码后的请求参数,将参数解码后在本地找到对应函数,本地执行对应函数并填充回包,再把回包编码通过网络连接返回。即在网络连接上实现双方无感知调用对方函数。

    参考文件

    记不得了,全网教程几乎都看了,参考太多了

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1440964.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

R语言rmarkdown使用

1、安装 install.packages(rmarkdown) library(rmarkdown) install.packages(tinytex) tinytex::install_tinytex() 2、新建R Markdown 3、基本框架 红色框内为YAML:包括标题、作者和日期等 黄色框内为代码块:执行后面的代码,并可以设置展…

Java风暴:打造高效作家信息管理平台

✍✍计算机编程指导师 ⭐⭐个人介绍:自己非常喜欢研究技术问题!专业做Java、Python、微信小程序、安卓、大数据、爬虫、Golang、大屏等实战项目。 ⛽⛽实战项目:有源码或者技术上的问题欢迎在评论区一起讨论交流! ⚡⚡ Java实战 |…

Spring Boot + 七牛OSS: 简化云存储集成

引言 Spring Boot 是一个非常流行的、快速搭建应用的框架,它无需大量的配置即可运行起来,而七牛云OSS提供了稳定高效的云端对象存储服务。利用两者的优势,可以为应用提供强大的文件存储功能。 为什么选择七牛云OSS? 七牛云OSS提供了高速的…

NGINX upstream、stream、四/七层负载均衡以及案例示例

文章目录 前言1. 四/七层负载均衡1.1 开放式系统互联模型 —— OSI1.2 四/七层负载均衡 2. Nginx七层负载均衡2.1 upstream指令2.2 server指令和负载均衡状态与策略2.2.1 负载均衡状态2.2.2 负载均衡策略 2.3 案例 3. Nginx四层负载均衡的指令3.1 stream3.2 upstream指令3.3 四…

排序算法---归并排序

原创不易,转载请注明出处。欢迎点赞收藏~ 归并排序是一种常见的排序算法,它采用了分治的思想。它将一个待排序的数组递归地分成两个子数组,分别对两个子数组进行排序,然后将排好序的子数组合并成一个有序数组。 具体的归并排序过…

Docker部署前端项目

某次阿里云的自动流水线失败了,代码本地跑起来莫得问题,错误日志提示让我跑一下npm run build ,但是俺忽然发现,我跑了,文件打包好了,但是往哪里运行呢?这涉及到要构建一个环境供打包文件部署吧…

Git的基础操作指令

目录 1 前言 2 指令 2.1 git init 2.2 touch xxx 2.3 git status 2.4 git add xxx 2.5 git commit -m xxxx 2.5 git log及git log --prettyoneline --all --graph --abbrev-commit 2.6 rm xxx 2.7 git reset --hard xxx(含小技巧) 2.8 git reflog 2.9 mv xxx yyy 1…

计算机考研数学】张宇1000题和660哪个更难?

1000题和660题都很难,难的不一样 660题是对于基础深入考察的难 660题是非常经典的客观题练习题,题目难度中等,不难但是每一道题都需要认真的思考才能做出来。如果660题能够吃透,并且每一道题的方法都能够灵活掌握的话&#xff0…

Python Paramiko 使用交互方式获取终端输出报错

近期接到一个需求,要批量登录网络设备获取配置。 原计划使用 Paramiko exec即可,但是后来发现,有些设备命令也执行了,但是没有回显。 于是尝试使用 invoke_shell() 方式。 前期调试倒是OK,直到遇见一个输出内容较长的…

python-pandas查漏补缺

1. create labels for Series 2. 3. 4. 用平均数等去填empty的格子 5. 6. 7.

读千脑智能笔记08_人工智能的未来(下)

1. 机器智能存在的风险 1.1. “人工智能”这个名字应用到几乎所有涉及机器学习的领域 1.2. 技术专家对人工智能的态度也从“人工智能可能永远不会实现”快速转变为“人工智能可能在不久的将来毁灭所有人类” 1.3. 每一项新技术都可能会被滥用…

springboo冬奥会科普平台源码和论文

随着信息技术和网络技术的飞速发展,人类已进入全新信息化时代,传统管理技术已无法高效,便捷地管理信息。为了迎合时代需求,优化管理效率,各种各样的管理平台应运而生,各行各业相继进入信息管理时代&#xf…

【Flink入门修炼】1-1 为什么要学习 Flink?

流处理和批处理是什么? 什么是 Flink? 为什么要学习 Flink? Flink 有什么特点,能做什么? 本文将为你解答以上问题。 一、批处理和流处理 早些年,大数据处理还主要为批处理,一般按天或小时定时处…

Ubuntu 22 部署Zabbix 6.4

一、安装及配置postgresql sudo apt-get update sudo apt-get install postgresql postgresql-client 修改配置文件,配置远程访问:(PostgreSQL安装路径下的data,也是安装时data的默认路径)data目录下的 pg_hba.conf …

火星文:网络时代下的语言

引言 在互联网时代,网络语言的发展日新月异。火星文作为一种特殊的网络表达方式,近年来逐渐兴起并成为了网络文化的一部分。 火星文生成器 | 一个覆盖广泛主题工具的高效在线平台(amd794.com) https://amd794.com/huoxingwen 火星文的兴起时代 火星…

为什么是0.1uF电容?

旁路电容是电子设计中常用的电容器之一,主要用于过滤电源噪声和稳定电源电压。在实际应用中,0.1uF电容器是最常用的旁路电容值之一,那么为什么常用旁路电容是0.1uF而不是其他值?这个值又是怎么来的呢?本文将深入探讨这…

FPGA_简单工程_数码管静态显示

一 理论 数码管是一种半导体发光器件,基本单位是发光二极管。 以六位八段数码管为例,每段需要一个端口信号,6814位。 74HC595芯片: 8位串行输入,并行输出的位移缓存器,其内部具有8位移位寄存器和一个存储…

[WUSTCTF2020]朴实无华(特详解)

一开始说header出问题了 就先dirsaerch扫一遍 发现robot.txt 访问一下 去看看&#xff0c;好好好&#xff0c;肯定不是得 他一开始说header有问题&#xff0c;不妨抓包看看&#xff0c;果然有东西 访问看看&#xff0c;乱码修复一下&#xff0c;在之前的博客到过 <img src…

如何连接ChatGPT?无需科学上网,使用官方GPT教程

随着AI的发展&#xff0c;ChatGPT也越来越强大了。 它可以帮你做你能想到的几乎任何事情&#xff0c;妥妥的生产力工具。 然而&#xff0c;对于许多国内的用户来说&#xff0c;并不能直接使用ChatGPT&#xff0c;不过没关系&#xff0c;我最近发现了一个可以直接免科学上网连…

【征稿已开启】第五大数据、人工智能与软件工程国际研讨会(ICBASE 2024)

第五大数据、人工智能与软件工程国际研讨会&#xff08;ICBASE 2024&#xff09; 2024 5th International Conference on Big Data & Artificial Intelligence & Software Engineering 2024年09月20-22日 | 中国温州 第五届大数据、人工智能与软件工程国际研讨会&…