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

网上的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 mainimport ("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 mainimport ("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://xiahunao.cn/news/2775924.html

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

相关文章

【MySQL】_JDBC编程

目录 1. JDBC原理 2. 导入JDBC驱动包 3. 编写JDBC代码实现Insert 3.1 创建并初始化一个数据源 3.2 和数据库服务器建立连接 3.3 构造SQL语句 3.4 执行SQL语句 3.5 释放必要的资源 4. JDBC代码的优化 4.1 从控制台输入 4.2 避免SQL注入的SQL语句 5. 编写JDBC代码实现…

《Git 简易速速上手小册》第2章:理解版本控制(2024 最新版)

文章目录 2.1 本地仓库与版本历史2.1.1 基础知识讲解2.1.2 重点案例:回滚错误提交2.1.3 拓展案例 1:利用 git bisect 查找引入 bug 的提交2.1.4 拓展案例 2:合并提交历史 2.2 远程仓库的使用2.2.1 基础知识讲解2.2.2 重点案例:在 …

midnightsun-2018-flitbip:任意地址写

题目下载 启动脚本 启动脚本如下,没开启任何保护 #!/bin/bash qemu-system-x86_64 \-m 128M \-kernel ./bzImage \-initrd ./initrd \-nographic \-monitor /dev/null \-append "nokaslr root/dev/ram rw consolettyS0 oopspanic paneic1 quiet" 2>…

预测模型:MATLAB线性回归

1. 线性回归模型的基本原理 线性回归是统计学中用来预测连续变量之间关系的一种方法。它假设变量之间存在线性关系,可以通过一个或多个自变量(预测变量)来预测因变量(响应变量)的值。基本的线性回归模型可以表示为&…

备战蓝桥杯---动态规划(基础2)

本专题主要是介绍几个比较经典的题目: 假设我们令f[i]为前i个的最长不下降子序列,我们会发现难以转移方程很难写(因为我们不知道最后一个数)。 于是,我们令f[i]为以i结尾的最长不下降子序列,这样子我们就可…

香港倾斜模型3DTiles数据漫游

谷歌地球全香港地区倾斜摄影数据,通过工具转换成3DTiles格式,将这份数据完美加载到三维数字地球Cesium上进行完美呈现,打造香港地区三维倾斜数据覆盖,完美呈现香港城市壮美以及维多利亚港繁荣景象。再由12.5米高分辨率地形数据&am…

SpringCloud-Ribbon:负载均衡(基于客户端)

6. Ribbon:负载均衡(基于客户端) 6.1 负载均衡以及Ribbon Ribbon是什么? Spring Cloud Ribbon 是基于Netflix Ribbon 实现的一套客户端负载均衡的工具。简单的说,Ribbon 是 Netflix 发布的开源项目,主要功能是提供客户端的软件负…

【Java EE】----SpringBoot的日志文件

1.SpringBoot使用日志 先得到日志对象通过日志对象提供的方法进行打印 2.打印日志的信息 3.日志级别 作用: 可以筛选出重要的信息不同环境实现不同日志级别的需求 ⽇志的级别分为:(1-6级别从低到高) trace:微量&#…

SCI 1区论文:Segment anything in medical images(MedSAM)[文献阅读]

基本信息 标题:Segment anything in medical images中文标题:分割一切医学图像发表年份: 2024年1月期刊/会议: Nature Communications分区: SCI 1区IF:16.6作者: Jun Ma; Bo Wang(一作;通讯)单位:加拿大多…

排序算法---插入排序

原创不易,转载请注明出处。欢迎点赞收藏~ 插入排序是一种简单直观的排序算法,它的基本思想是将待排序的元素分为已排序和未排序两部分,每次从未排序部分中选择一个元素插入到已排序部分的合适位置,直到所有元素都插入到已排序部分…

微软技术专家带你学 AI|Azure OpenAI 服务

点击蓝字 关注我们 编辑:Alan Wang 排版:Rani Sun 微软技术专家带你学 AI 新的一年,为帮助开发者们在 Azure 上掌握人工智能,我们特别带来「微软技术专家带你学 AI」系列,通过4期的课程,带大家从机器学习的…

ES高可用架构涉及常用功能整理

ES高可用架构涉及常用功能整理 1. es的高可用系统架构和相关组件2. es的核心参数2.1 常规配置2.2 特殊优化配置2.2.1 数据分片按ip打散2.2.2 数据分片机架感知2.2.3 强制要求数据分片机架感知2.2.4 写入线程池优化2.2.5 分片balance优化2.2.6 限流控制器优化 3. es常用命令3.1 …

在屏蔽任何FRP环境下从零开始搭建安全的FRP内网穿透服务

背景 本人目前在境外某大学读博,校园网屏蔽了所有内网穿透的工具的数据包和IP访问,为了实现在家也能远程访问服务器,就不得不先开个学校VPN,再登陆。我们实验室还需要访问另一个大学的服务器,每次我都要去找另一个大学…

海外云手机——平台引流的重要媒介

随着互联网的飞速发展,跨境电商、短视频引流以及游戏行业等领域正经历着迅猛的更新换代。在这个信息爆炸的时代,流量成为至关重要的资源,而其中引流环节更是关乎业务成功的关键。海外云手机崭露头角,成为这一传播过程中的重要媒介…

消息中间件:Puslar、Kafka、RabbigMQ、ActiveMQ

消息队列 消息队列:它主要用来暂存生产者生产的消息,供后续其他消费者来消费。 它的功能主要有两个: 暂存(存储)队列(有序:先进先出 从目前互联网应用中使用消息队列的场景来看,…

【龙年大礼】| 2023中国开源年度报告!

【中国开源年度报告】由开源社从 2015 年发起,是国内首个结合多个开源社区、高校、媒体、风投、企业与个人,以纯志愿、非营利的理念和开源社区协作的模式,携手共创完成的开源研究报告。后来由于一些因素暂停,在 2018 年重启了这个…

Qt PCL学习(二):点云读取与保存

注意事项 版本一览:Qt 5.15.2 PCL 1.12.1 VTK 9.1.0前置内容:Qt PCL学习(一):环境搭建 0. 效果演示 1. pcl_open_save.pro QT core guigreaterThan(QT_MAJOR_VERSION, 4): QT widgets// 添加下行代码&#…

[word] word2019段落中创建纵横混排的方法图解教程 #知识分享#其他#职场发展

word2019段落中创建纵横混排的方法图解教程 有时候在word文档中需要让文字纵横混排,word2019正好为我们带来了纵横混排的功能了,今天我们就来给大家介绍一下word2019段落中创建纵横混排的方法。 步骤1:打开Word文档,选中需要纵向…

MT4和MT5中如何创建挂单,很简单,fpmarkets1秒教会

其实在MT4和MT5中创建挂单是非常容易的,今天fpmarkets1秒教会,接下来一步一步的演示: 首先单击新订单,将出现设置窗口。在“类型”选项卡中选择“按待定顺序”。 接着选择挂单的类型。选择买入止损单,并指定订单执行的…

【Leetcode】236. 二叉树的最近公共祖先

文章目录 题目思路代码结果 题目 题目链接 给定一个二叉树, 找到该树中两个指定节点的最近公共祖先。 百度百科中最近公共祖先的定义为:“对于有根树 T 的两个节点 p、q,最近公共祖先表示为一个节点 x,满足 x 是 p、q 的祖先且 x 的深度尽可…