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建立连接,传输编码后的请求参数,将参数解码后在本地找到对应函数,本地执行对应函数并填充回包,再把回包编码通过网络连接返回。即在网络连接上实现双方无感知调用对方函数。
参考文件
记不得了,全网教程几乎都看了,参考太多了
相关文章:
Window环境下使用go编译grpc最新教程
网上的grpc教程都或多或少有些老或者有些问题,导致最后执行生成文件时会报很多错。这里给出个人实践出可执行的编译命令与碰到的报错与解决方法。(ps:本文代码按照煎鱼的教程编写:4.2 gRPC Client and Server - 跟煎鱼学 Go (gitbook.io)&…...
STM32——FLASH(1)简单介绍、分类、读写流程及注意事项
文章目录 FLASH的特点Nor flash和nand flashflash的读写flash 的存储单位 flash的读写过程 FLASH的特点 可擦写数据可修改可重写访问速度<ROM Nor flash和nand flash Nor flash 1、与SDRAM相似,用户可以直接运行装载到NORFLASH里面的代码,减少SRAM…...
MySQL的DML语言
DML:Data Manipulation Language(数据操作语言) DML语言用来对数据库中表的数据记录进行增、删、改操作。 一、添加数据命令 注意: 插入数据时,指定的字段顺序需要与值的顺序是一一对应的。 字符串和日期型数据应该包…...
Vivado-IP核
Vivado-IP核 主程序 timescale 1ns / 1ps ////module ip_clk_wiz(input sys_clk,input sys_rst_n,output clk_out1,output clk_out2,output clk_out3,output clk_out4,output locked);clk_wiz_0 instance_name(// Clock out ports.clk_out1(clk_out1), // output clk_out…...
品牌如何营造生活感氛围?媒介盒子分享
「生活感」简而言之是指人们对生活的感受和意义,它往往没有充斥在各种重要的场合和事件中,而是更隐藏在细碎平凡的生活场景中。在营销越来越同质化的当下,品牌应该如何打破常规模式,洞察消费情绪,找到更能打动消费者心…...
Java 学习和实践笔记(2)
今天的学习进度: 注册并下载安装好了Java 8,之后进行以下配置。 1)path 是一个常见的环境变量,它告诉系统除了在当前的目标下妹寻找此程序外,还可以到path指定的目录下找。这句话是什么意思呢?以下举报例…...
Python:批量url链接保存为PDF
我的数据是先把url链接获取到存入excel中,后续对excel做的处理,各位也可以直接在程序中做处理,下面就是针对excel中的链接做批量处理 excel内容格式如下(涉及具体数据做了隐藏) 标题文件链接文件日期网页标题1http://…...
【LeetCode每日一题】525连续数组 303区域和检索(前缀和的基本概念和3个简单案例)
前缀和 // 构造prefix let prefix [0] arr.forEach(num > {prefix.push(prefix.at(-1) num); })如果想要计算某个区间 i 到 j 这个子数组的和时,可以根据 prefix[j1] - prefix[i] 获得。 例题1:303.区域和检索 - 数组不可变 给定一个整数数组 num…...
形态学算法应用之连通分量提取的python实现——图像处理
原理 连通分量提取是图像处理和计算机视觉中的一项基本任务,旨在识别图像中所有连通区域,并将它们作为独立对象处理。在二值图像中,连通分量通常指的是所有连接在一起的前景像素集合。这里的“连接”可以根据四连通或八连通的邻接关系来定义…...
Kafka系列之:Kafka集群同时设置基于时间和日志大小两种方式保存Topic的数据
Kafka系列之:Kafka集群同时设置基于时间和日志大小两种方式保存Topic的数据 一、基于日志大小二、基于时间大小三、参数设置四、设置命令一、基于日志大小 "log.retention.bytes"是Apache Kafka中的一项配置参数,用于指定每个日志段文件的最大大小。当日志段文件的…...
pytest+allure批量执行测试用例
在 Pytest 中,可以使用装饰器 `@pytest.fixture` 来定义用例级别的前置和后置操作。下面是一个示例代码,演示了如何使用 Pytest 的前置和后置操作: ```python import pytest @pytest.fixture(scope="function") def setup_function(): print("Setup fu…...
SpringBoot和SpringMVC
目录 一、springboot项目 (1)创建springboot项目 (2)目录介绍 (3)项目启动 (4)运行一个程序 (5)通过其他方式创建和运行springboot项目 二、SpringMVC…...
免费搭建幻兽帕鲁服务器,白嫖阿里云游戏服务器
阿里云幻兽帕鲁服务器免费搭建方案,先在阿里云高校计划「云工开物」活动领取学生专享300元无门槛代金券,幻兽帕鲁专用服务器4核16G配置26元1个月、149元半年,直接使用这个无门槛300元代金券抵扣即可免费搭建幻兽帕鲁服务器。阿里云服务器网al…...
[技术杂谈]如何下载vscode历史版本
网站模板: https://code.visualstudio.com/updates/v1_85 如果你想下载1.84系列可以访问https://code.visualstudio.com/updates/v1_84 然后看到: 选择对应版本下载即可,我是windows x64系统选择x64即可开始下载...
nginx slice模块的使用和源码分析
文章目录 1. 为什么需要ngx_http_slice_module2. 配置指令3. 加载模块4. 源码分析4.1 指令分析4.2 模块初始化4.3 slice模块的上下文4.2 $slice_range字段值获取4.3 http header过滤处理4.4 http body过滤处理5 测试和验证 1. 为什么需要ngx_http_slice_module 顾名思义&#…...
AI应用开发-python实现redis数据存储
AI应用开发相关目录 本专栏包括AI应用开发相关内容分享,包括不限于AI算法部署实施细节、AI应用后端分析服务相关概念及开发技巧、AI应用后端应用服务相关概念及开发技巧、AI应用前端实现路径及开发技巧 适用于具备一定算法及Python使用基础的人群 AI应用开发流程概…...
2024年Java架构篇之设计模式
2024年Java实战面试题_java 5 年 面试-CSDN博客 1、单例模式...
搭建macOS开发环境-1:准备工作
请记住: 最重要的准备工作永远是:备份数据 !!! 通过图形界面检查 Mac 的 CPU 类型: 在搭载 Apple 芯片的 Mac 电脑上,“关于本机”会显示一个标有“芯片”的项目并跟有相应芯片的名称: 通过命令行检查Mac的CPU类型 …...
【Makefile语法 02】Makefile语法基础
目录 一、Makefile概述 二、Makefile变量 三、Makefile符号 一、Makefile格式 1. 基本格式: targets : prerequisties [tab键]command target:目标文件,可以是 OjectFile,也可以是执行文件,还可以是一个标签&…...
如何写一个其他人可以使用的GitHub Action
前言 在GitHub中,你肯定会使用GitHub Actions自动部署一个项目到GitHub Page上,在这个过程中总要使用workflows工作流,并在其中使用action,在这个使用的过程中,总会好奇怎么去写一个action呢,所以ÿ…...
以下是对华为 HarmonyOS NETX 5属性动画(ArkTS)文档的结构化整理,通过层级标题、表格和代码块提升可读性:
一、属性动画概述NETX 作用:实现组件通用属性的渐变过渡效果,提升用户体验。支持属性:width、height、backgroundColor、opacity、scale、rotate、translate等。注意事项: 布局类属性(如宽高)变化时&#…...
Docker 运行 Kafka 带 SASL 认证教程
Docker 运行 Kafka 带 SASL 认证教程 Docker 运行 Kafka 带 SASL 认证教程一、说明二、环境准备三、编写 Docker Compose 和 jaas文件docker-compose.yml代码说明:server_jaas.conf 四、启动服务五、验证服务六、连接kafka服务七、总结 Docker 运行 Kafka 带 SASL 认…...
【OSG学习笔记】Day 16: 骨骼动画与蒙皮(osgAnimation)
骨骼动画基础 骨骼动画是 3D 计算机图形中常用的技术,它通过以下两个主要组件实现角色动画。 骨骼系统 (Skeleton):由层级结构的骨头组成,类似于人体骨骼蒙皮 (Mesh Skinning):将模型网格顶点绑定到骨骼上,使骨骼移动…...
Android Bitmap治理全解析:从加载优化到泄漏防控的全生命周期管理
引言 Bitmap(位图)是Android应用内存占用的“头号杀手”。一张1080P(1920x1080)的图片以ARGB_8888格式加载时,内存占用高达8MB(192010804字节)。据统计,超过60%的应用OOM崩溃与Bitm…...
Java编程之桥接模式
定义 桥接模式(Bridge Pattern)属于结构型设计模式,它的核心意图是将抽象部分与实现部分分离,使它们可以独立地变化。这种模式通过组合关系来替代继承关系,从而降低了抽象和实现这两个可变维度之间的耦合度。 用例子…...
根目录0xa0属性对应的Ntfs!_SCB中的FileObject是什么时候被建立的----NTFS源代码分析--重要
根目录0xa0属性对应的Ntfs!_SCB中的FileObject是什么时候被建立的 第一部分: 0: kd> g Breakpoint 9 hit Ntfs!ReadIndexBuffer: f7173886 55 push ebp 0: kd> kc # 00 Ntfs!ReadIndexBuffer 01 Ntfs!FindFirstIndexEntry 02 Ntfs!NtfsUpda…...
Vue ③-生命周期 || 脚手架
生命周期 思考:什么时候可以发送初始化渲染请求?(越早越好) 什么时候可以开始操作dom?(至少dom得渲染出来) Vue生命周期: 一个Vue实例从 创建 到 销毁 的整个过程。 生命周期四个…...
Python 训练营打卡 Day 47
注意力热力图可视化 在day 46代码的基础上,对比不同卷积层热力图可视化的结果 import torch import torch.nn as nn import torch.optim as optim from torchvision import datasets, transforms from torch.utils.data import DataLoader import matplotlib.pypl…...
自然语言处理——文本分类
文本分类 传统机器学习方法文本表示向量空间模型 特征选择文档频率互信息信息增益(IG) 分类器设计贝叶斯理论:线性判别函数 文本分类性能评估P-R曲线ROC曲线 将文本文档或句子分类为预定义的类或类别, 有单标签多类别文本分类和多…...
CSS3相关知识点
CSS3相关知识点 CSS3私有前缀私有前缀私有前缀存在的意义常见浏览器的私有前缀 CSS3基本语法CSS3 新增长度单位CSS3 新增颜色设置方式CSS3 新增选择器CSS3 新增盒模型相关属性box-sizing 怪异盒模型resize调整盒子大小box-shadow 盒子阴影opacity 不透明度 CSS3 新增背景属性ba…...
