gRPC和gRPC-Gateway的使用以及遇到的坑
原创不易,未经允许,请勿转载。
文章目录
- 一、gRPC的使用
- 1.1 gPRC和Protobuf的安装
- 1.2 编写proto文件
- 1.3 编写服务端接口程序
- 1.4 编写客户端程序
- 二、gRPC-Gateway的使用
- 2.1 安装grpc-gateway
- 2.2 编写proto文件
- 2.3 编写服务端代码
- 2.4 编写http转发代码
- 2.5 测试
- 三、可能遇到的坑
系统:windows10
go版本:1.13.15
一、gRPC的使用
1.1 gPRC和Protobuf的安装
go get github.com/golang/protobuf/proto
go get google.golang.org/grpc
go get github.com/golang/protobuf/protoc-gen-go
装好上面三个之后,还需要安装一个protoc
,可以到https://github.com/protocolbuffers/protobuf/releases/tag/v3.9.0下载编译好的可执行文件,然后把压缩包中bin
目录下的protoc.exe
放到GOPATH/bin
目录下。
压缩包里面的include目录也放到GOPATH/bin目录下,之后用得到
现在,可以在GOPATH/bin
目录下,看到protoc-gen-go.exe
和protoc.exe
这两个可执行文件
1.2 编写proto文件
在编写文件之间,先创建一个go项目,命名为grpc_and_grpc-gateway_demo
,以grpc_and_grpc-gateway_demo
为根目录,创建一个文件名为proto/helloworld.proto
protobuf
语法可以参考https://www.jianshu.com/p/4443c28d4bf7
syntax = "proto3";
package helloworld; // 指定生成后go的package名
option go_package = "helloworld/"; // 生成的目录名,末尾的/不能省略,否则会出错。
message request {string name = 1;
}
message response {string res = 1;
}service HelloWorld {rpc Call(request) returns(response){}
}
编写好proto文件后,打开命令行窗口,进入proto目录下
cd proto
使用protoc
编译helloworld.proto
文件,生成对应的go
文件
protoc --go_out=plugins=grpc:. ./helloworld.proto
--go_out
表示生成go文件。grpc:.
冒号后面表示生成文件保存的位置,这个路径要已存在。.
表示当前目录。helloworld.proto
表示要编译的文件名
执行好上面的命令后,如果没出错的话,在proto
目录下会生成一个helloworld/helloworld.pb.go
文件
其中helloworld
为文件夹名,就算go_package
指定的目录名。
helloworld.pb.go
文件包含按照helloworld.proto
文件描述的,服务端接口HelloWorldServer
,客户端接口以及实现HelloWorldClient
,以及Request
、Response
结构体
1.3 编写服务端接口程序
以grpc_and_grpc-gateway_demo
为根目录,创建server/main.go
package mainimport ("context""fmt""google.golang.org/grpc"pb "grpc_and_grpc-gateway_demo/proto/helloworld""net"
)type helloWorldServer struct{}func (this helloWorldServer) Call(ctx context.Context, request *pb.Request) (*pb.Response, error) {resp := new(pb.Response)resp.Res = "Hello " + request.Namereturn resp, nil
}func main() {listen, err := net.Listen("tcp", "127.0.0.1:8080")if err != nil {fmt.Println(err)return}defer listen.Close()s := grpc.NewServer()pb.RegisterHelloWorldServer(s,helloWorldServer{})fmt.Println("Listen on 127.0.0.1:8080")s.Serve(listen)
}
运行该程序
go run main.go
1.4 编写客户端程序
以grpc_and_grpc-gateway_demo
为根目录,创建client/main.go
package mainimport ("context""fmt""google.golang.org/grpc"pb "grpc_and_grpc-gateway_demo/proto/helloworld"
)func main() {conn, err := grpc.Dial("127.0.0.1:8080", grpc.WithInsecure())if err != nil {fmt.Println(err)}defer conn.Close()c := pb.NewHelloWorldClient(conn)req := &pb.Request{Name: "jiang"}res, err := c.Call(context.Background(), req)if err != nil {fmt.Println(err)}fmt.Println(res.Res)
}
运行该程序
go run main.go
最后打印
Hello jiang
二、gRPC-Gateway的使用
通过protobuf的自定义option实现了一个网关,服务端同时开启gRPC和HTTP服务,HTTP服务接收客户端请求后转换为grpc请求数据,获取响应后转为json数据返回给客户端。
2.1 安装grpc-gateway
安装推荐去grpc-gateway
的GitHub仓库,看最新的文档进行,安装,
go get github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-grpc-gateway
一些博客教程里面写的安装命令是下面这种
go get -u github.com/grpc-ecosystem/grpc-gateway/protoc-gen-grpc-gateway
但是用这个命令安装的话,在后面执行命令的时候,会出现一些错误,可能会打印出一长串东西,结尾大概如下
--grpc-gateway_out: 11:1: expected 'IDENT', found 'import'
2.2 编写proto文件
以grpc_and_grpc-gateway_demo
为根目录,创建一个文件名为proto/helloworld_http.proto
syntax = "proto3";
package helloworld_http; // 指定生成后go的package名
option go_package = "helloworld_http/"; // 生成的目录名,末尾的/不能省略,否则会出错。import "google/api/annotations.proto"; message request {string name = 1;
}
message response {string res = 1;
}service HelloWorldHTTP {rpc Call(request) returns(response){option (google.api.http) = {post : "/hello/world/call"body : "*"};}
}
在编译前,还需要把google/api/annotations.proto
等文件复制到proto
目录下。
如果你本地下载了github.com\grpc-ecosystem\grpc-gateway
的1.0+
版本的话,进入该项目目录,找到third_party\googleapis
项目中的这个目录,然后把里面的google
文件夹整个复制到proto
目录下即可。
如果没有下载1.0+
版本的话,可以到这个GitHub上去拷贝https://github.com/grpc-ecosystem/grpc-gateway/tree/v1/third_party/googleapis
protoc --go_out=plugins=grpc:. .\helloworld_http.proto
protoc --grpc-gateway_out=logtostderr=true:. .\helloworld_http.proto
两个命令执行完后,没出错误的话,会在proto
目录下生成两个文件:helloworld_http/helloworld_http.pb.go
、helloworld_http/helloworld_http.pb.gw.go
2.3 编写服务端代码
以grpc_and_grpc-gateway_demo
为根目录,创建server_http/server.go
package mainimport ("context""fmt""google.golang.org/grpc"pb "grpc_and_grpc-gateway_demo/proto/helloworld_http" // 编译生成的包"net"
)type helloWorldServer struct{}func (this helloWorldServer) Call(ctx context.Context, request *pb.Request) (*pb.Response, error) {resp := new(pb.Response)resp.Res = "Hello " + request.Namereturn resp, nil
}func main() {listen, err := net.Listen("tcp", "127.0.0.1:8080")if err != nil {fmt.Println(err)return}defer listen.Close()s := grpc.NewServer()pb.RegisterHelloWorldHTTPServer(s,helloWorldServer{})fmt.Println("Listen on 127.0.0.1:8080")s.Serve(listen)
}
运行代码
go run server.go
2.4 编写http转发代码
以grpc_and_grpc-gateway_demo
为根目录,创建server_http/main.go
package mainimport ("context""fmt""github.com/grpc-ecosystem/grpc-gateway/v2/runtime""google.golang.org/grpc""grpc_and_grpc-gateway_demo/proto/helloworld_http""net/http"
)func main() {ctx := context.Background()ctx, cancel := context.WithCancel(ctx)defer cancel()// grpc服务地址endpoint := "127.0.0.1:8080"mux := runtime.NewServeMux()opts := []grpc.DialOption{grpc.WithInsecure()}// HTTP转grpcerr := helloworld_http.RegisterHelloWorldHTTPHandlerFromEndpoint(ctx, mux, endpoint, opts)if err != nil {fmt.Println("Register handler err:%v\n", err)}// http监听的端口fmt.Println("HTTP Listen on 8088")http.ListenAndServe(":8088", mux)
}
运行代码
go run main.go
2.5 测试
打开postmain或者其他接口测试工具,往以下地址发送请求,请求方法为POST
http://localhost:8088/hello/world/call
请求体为一个json数据
{"name":"jiang"
}
请求方法为上面proto文件中option定义的,请求地址/hello/world/call
也一样是上面定义好的。
json数据name为request的内容。
三、可能遇到的坑
这个坑在上面提到过一次了,在这里再说一下,因为这个坑, 浪费博主一两个小时的时间。
一开始安装protoc-gen-grpc-gateway
的时候,我也是用下面的命令安装的
go get -u github.com/grpc-ecosystem/grpc-gateway/protoc-gen-grpc-gateway
结果在编译这个命令的时候,不能正常生成文件,反而打印了一堆奇奇怪怪的东西。
protoc --grpc-gateway_out=logtostderr=true:. .\helloworld_http.proto
生成如下乱码。
E1207 15:44:17.874478 15920 generator.go:108] 11:1: expected 'IDENT', found 'import':
// Code generated by protoc-gen-grpc-gateway. DO NOT EDIT.
// source: hello.proto/*
Package is a reverse proxy.It translates gRPC into RESTful JSON APIs......
.....--grpc-gateway_out: 11:1: expected 'IDENT', found 'import'
后来看了github上的文档才解决的。
拒绝白嫖从一键三连开始!
原创不易,未经允许,请勿转载。
博客主页:https://xiaojujiang.blog.csdn.net/
gRPC和gRPC-Gateway的使用以及遇到的坑相关推荐
- 带入gRPC:gRPC Streaming, Client and Server
带入gRPC:gRPC Streaming, Client and Server 原文地址:带入gRPC:gRPC Streaming, Client and Server 项目地址:go-grpc- ...
- php yat grpc,PHP GRPC 模块安装配置-Go语言中文社区
protobuf 文件编译成PHP文件 lisa.proto文件syntax = "proto3"; package lisa; // The greeting service d ...
- go grpc压缩_跟我学 gRPC—1. gRPC 及相关介绍
Go语言中文网,致力于每日分享编码.开源等知识,欢迎关注我,会有意想不到的收获! 项目地址:https://github.com/EDDYCJY/go-grpc-example 作为开篇章,将会介绍 ...
- java grpc protobuf_protobuf+grpc+examples
从下载后的grpc-java-master中的examples pom.xml是有问题的 以下是修改后的pom.xml,注意JDK版本要在1.6或以上 xsi:schemaLocation=" ...
- Grpc+Grpc Gateway实践二 有些复杂的Hello World
Hello World 在上一节中我们已经完成了对环境的基本配置 这节将开始编写一个复杂的Hello World,涉及到许多的知识,建议大家认真思考其中的概念 需求 由于本实践偏向Grpc+Grpc ...
- Grpc+Grpc Gateway实践一 介绍与环境安装
介绍与环境安装 假定我们有一个项目需求,希望用Rpc作为内部API的通讯,同时也想对外提供Restful Api,写两套又太繁琐不符合 于是我们想到了Grpc以及Grpc Gateway,这就是我们所 ...
- grpc+gateway使用说明
文章目录 grpc+gateway 使用说明(MAC版) 1. 安装 1.1 安装golang 1.2 安装protoc 1.3 安装grpc相关脚本 2. 编写protoc文件 2.1 添加prot ...
- go语言使用grpc和gateway教程
jsonrpc 把jsonrpc.ServeConn(conn)改为grpc.ServeConn(conn)就是grpc了 为什么用jsongrpc? 因为grpc使用的为go语言独有的数据序列化go ...
- Envoy实现.NET架构的网关(三)代理GRPC
.NET网关与Gateway实战-Envoy与kong课程 Envoy实现.NET架构的网关(一)静态配置与文件动态配置 Envoy实现.NET架构的网关(二)基于控制平面的动态配置 什么是GRPC ...
- Golang gRPC实践 连载七 HTTP协议转换
gRPC HTTP协议转换 正当有这个需求的时候,就看到了这个实现姿势.源自coreos的一篇博客,转载到了grpc官方博客gRPC with REST and Open APIs. etcd3改用g ...
最新文章
- Mac笔记本中是用Idea开发工具在Java项目中调用python脚本遇到的环境变量问题解决...
- hive整合sentry,impala,hue之后权限管理操作
- python界面不同按钮实现不同功能-python tkinter实现界面切换的示例代码
- 获取Windwos的版本和名称 -- GetVersion|GetVersionEx
- 人工智能火热,该如何学Python呢?
- mysql经典面试题
- 【SAS NOTES】if then和if的区别
- polkit 重新安装_不折腾,为U-NAS安装一个清爽的桌面,把小U打造成双面高手
- ES6 iterator 迭代器
- WinPcap笔记(2):获取设备列表
- 【PHP】月末・月初の出力方法
- 软考网络工程师笔记-综合知识3
- 《深入应用C++11:代码优化与工程级应用》勘误表
- matlab dpabi安装,Android 8 应用安装时 ABI 确认过程
- java实现连接linux,JAVA实现远道SSH连接linux并执行命令
- 十二、Vue项目 - 详情页动态路由、banner布局和公用图片画廊组件拆分
- 【结论】加工生产调度
- 无人船,水下地形测绘无人船,水质取样监测无人船,无人巡逻船
- 《Cisco IPv6网络实现技术(修订版)》一1.5 IPv5
- GitHub上整理的一些工具,求补充