原创不易,未经允许,请勿转载。

文章目录

  • 一、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.exeprotoc.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,以及RequestResponse结构体

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-gateway1.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.gohelloworld_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的使用以及遇到的坑相关推荐

  1. 带入gRPC:gRPC Streaming, Client and Server

    带入gRPC:gRPC Streaming, Client and Server 原文地址:带入gRPC:gRPC Streaming, Client and Server 项目地址:go-grpc- ...

  2. php yat grpc,PHP GRPC 模块安装配置-Go语言中文社区

    protobuf 文件编译成PHP文件 lisa.proto文件syntax = "proto3"; package lisa; // The greeting service d ...

  3. go grpc压缩_跟我学 gRPC—1. gRPC 及相关介绍

    Go语言中文网,致力于每日分享编码.开源等知识,欢迎关注我,会有意想不到的收获! 项目地址:https://github.com/EDDYCJY/go-grpc-example 作为开篇章,将会介绍 ...

  4. java grpc protobuf_protobuf+grpc+examples

    从下载后的grpc-java-master中的examples pom.xml是有问题的 以下是修改后的pom.xml,注意JDK版本要在1.6或以上 xsi:schemaLocation=" ...

  5. Grpc+Grpc Gateway实践二 有些复杂的Hello World

    Hello World 在上一节中我们已经完成了对环境的基本配置 这节将开始编写一个复杂的Hello World,涉及到许多的知识,建议大家认真思考其中的概念 需求 由于本实践偏向Grpc+Grpc ...

  6. Grpc+Grpc Gateway实践一 介绍与环境安装

    介绍与环境安装 假定我们有一个项目需求,希望用Rpc作为内部API的通讯,同时也想对外提供Restful Api,写两套又太繁琐不符合 于是我们想到了Grpc以及Grpc Gateway,这就是我们所 ...

  7. grpc+gateway使用说明

    文章目录 grpc+gateway 使用说明(MAC版) 1. 安装 1.1 安装golang 1.2 安装protoc 1.3 安装grpc相关脚本 2. 编写protoc文件 2.1 添加prot ...

  8. go语言使用grpc和gateway教程

    jsonrpc 把jsonrpc.ServeConn(conn)改为grpc.ServeConn(conn)就是grpc了 为什么用jsongrpc? 因为grpc使用的为go语言独有的数据序列化go ...

  9. Envoy实现.NET架构的网关(三)代理GRPC

    .NET网关与Gateway实战-Envoy与kong课程 Envoy实现.NET架构的网关(一)静态配置与文件动态配置 Envoy实现.NET架构的网关(二)基于控制平面的动态配置 什么是GRPC ...

  10. Golang gRPC实践 连载七 HTTP协议转换

    gRPC HTTP协议转换 正当有这个需求的时候,就看到了这个实现姿势.源自coreos的一篇博客,转载到了grpc官方博客gRPC with REST and Open APIs. etcd3改用g ...

最新文章

  1. Mac笔记本中是用Idea开发工具在Java项目中调用python脚本遇到的环境变量问题解决...
  2. hive整合sentry,impala,hue之后权限管理操作
  3. python界面不同按钮实现不同功能-python tkinter实现界面切换的示例代码
  4. 获取Windwos的版本和名称 -- GetVersion|GetVersionEx
  5. 人工智能火热,该如何学Python呢?
  6. mysql经典面试题
  7. 【SAS NOTES】if then和if的区别
  8. polkit 重新安装_不折腾,为U-NAS安装一个清爽的桌面,把小U打造成双面高手
  9. ES6 iterator 迭代器
  10. WinPcap笔记(2):获取设备列表
  11. 【PHP】月末・月初の出力方法
  12. 软考网络工程师笔记-综合知识3
  13. 《深入应用C++11:代码优化与工程级应用》勘误表
  14. matlab dpabi安装,Android 8 应用安装时 ABI 确认过程
  15. java实现连接linux,JAVA实现远道SSH连接linux并执行命令
  16. 十二、Vue项目 - 详情页动态路由、banner布局和公用图片画廊组件拆分
  17. 【结论】加工生产调度
  18. 无人船,水下地形测绘无人船,水质取样监测无人船,无人巡逻船
  19. 《Cisco IPv6网络实现技术(修订版)》一1.5 IPv5
  20. GitHub上整理的一些工具,求补充

热门文章

  1. 全志A10/A20 Bootloader加载过程分析
  2. python中采用字典建立统_Python字典的基本使用
  3. python中gbk字符原因报错_深入理解Python中的字符和编码,结合,了解,与
  4. XZ_iOS之优秀网站推荐
  5. 智能泥石流泥水位监测预警系统解决方案
  6. vim滚动屏幕快捷键汇总
  7. 2014年最新Itcast C++培训3期培训班视频教程
  8. 怎么做餐饮行业的引流?
  9. 杭电计算机考研初试经验
  10. 数据结构应用题第三章栈和队列代码c