学习来源

https://naotu.baidu.com/file/c80e753e20e8ab18a80cb573ac08e912?token=e89e127e95b325d5
https://www.bilibili.com/video/BV1Ev411w7yu/?spm_id_from=333.788&vd_source=53e5d5a8d002898905d03bcc15ef7842

安装协议包

当前go版本 go1.15.6
1.创建proto后缀文件,配置。
2.goland 搜索 grpc插件安装
3.https://grpc.io/docs/languages/go/quickstart/ 快速开始,安装包。
这个并非是安装到项目中的仓库的
image.png
image.png
执行报错。提示这种带版本的方式只能用go get方式来获取。根据go的版本不同。高版本的可以用go install 。
此时,gopath下的bin目录下,两条命令均执行完后会多出两个可执行文件:
image.png
4.安装protoc.exe,便于生成文件
https://github.com/protocolbuffers/protobuf/releases/tag/v3.9.0 下载解压提取里面的可执行文件,并放置到上述bin目录下。
image.png

安装grpc包

go get google.golang.org/grpc

image.png

编译proto文件

image.png
文件内容:

  1. syntax = "proto3";
  2. package hello_grpc;
  3. option go_package = "./;hello_grpc";
  4. message Req {
  5. string message = 1;
  6. }
  7. message Res {
  8. string message = 1;
  9. }
  10. service HelloeGRPC {
  11. rpc SayHi(Req) returns (Res);
  12. }

这里的go_package,包名,需跟package一致,方便调用。

编译命令

protoc —go_out=. —go_opt=paths=source_relative —go-grpc_out=. —go-grpc_opt=paths=source_relative ./hello_grpc.proto

这个比较长,可以将此命令做成一个bat文件,放置于hello_grpc.proto的同个文件夹下。
goland里面使用命令行获取到的gopath或者是gobin有可能跟系统设置的不一样。
如果报以下错误,说明程序没有正确找到插件的位置。需要手动指定位置:
image.png

protoc —plugin=protoc-gen-go=%GOBIN%/protoc-gen-go.exe —plugin=protoc-gen-go-grpc=%GOBIN%/protoc-gen-go-grpc.exe —go_out=. —go_opt=paths=source_relative —go-grpc_out=. —go-grpc_opt=paths=source_relative ./hello_grpc.proto

所以还是到命令行里面执行:
image.png

执行命令

生成了两个go文件。
image.png

至此grpc环境已经完成

开始使用grpc

先创建服务端

创建client和server文件夹。分别代表两个服务,做调用过程。
先写服务端,分为4个步骤

  1. 取出server
  2. 挂载方法
  3. 注册服务
  4. 创建监听

官网给出的使用示例:
image.png
到这个github仓库中,查看示例。https://github.com/grpc/grpc-go
参考这个:image.png
代码敲入 grpc.NewServer()。出不来时,需要设置goland的gopath
image.png
服务端代码

  1. package main
  2. import (
  3. "context"
  4. "fmt"
  5. "google.golang.org/grpc"
  6. hello_grpc "grpc_test/pb"
  7. "net"
  8. )
  9. //1.声明服务,组合服务接口
  10. type Server struct {
  11. //这里组合进一个刚生成出来的空接口,我们需要实现这个接口中的方法
  12. //而这个方法正是hello_grpc.proto中的定义的方法。
  13. //这个接口的名称也包含了proto文件中service的名称。
  14. hello_grpc.UnimplementedHelloeGRPCServer
  15. }
  16. //2.挂载方法。这个就是服务端对外暴露的方法。在proto文件中也要声明这个方法
  17. //返回的是个指针
  18. func (s Server) SayHi(ctx context.Context, req *hello_grpc.Req) (res *hello_grpc.Res, err error) {
  19. fmt.Println(req.GetMessage())
  20. //
  21. return &hello_grpc.Res{
  22. Message: "这是从服务端返回的msg",
  23. }, nil
  24. }
  25. func main() {
  26. //3.注册服务
  27. listener, err := net.Listen("tcp", ":8888")
  28. if err != nil {
  29. fmt.Println("监听8888端口失败")
  30. }
  31. grpc_server := grpc.NewServer()
  32. //将我们提供的服务和grpc的服务绑定起来
  33. hello_grpc.RegisterHelloeGRPCServer(grpc_server, &Server{})
  34. //4.监听服务
  35. err = grpc_server.Serve(listener)
  36. if err != nil {
  37. fmt.Println("监听8888端口失败-2")
  38. }
  39. }

创建客户端

参考客户端示例:
image.png
客户端代码

  1. package main
  2. import (
  3. "context"
  4. "fmt"
  5. "google.golang.org/grpc"
  6. "google.golang.org/grpc/credentials/insecure"
  7. hello_grpc "grpc_test/pb"
  8. )
  9. func main() {
  10. //1.创建连接
  11. conn, err := grpc.Dial(":8888", grpc.WithTransportCredentials(insecure.NewCredentials()))
  12. defer conn.Close()
  13. if err != nil {
  14. //如果grpc.Dial(":8888"),仅这样会报错,看提示报错加上后面的参数
  15. fmt.Println(err)
  16. fmt.Println("创建连接失败")
  17. }
  18. //2.创建客户端
  19. client := hello_grpc.NewHelloeGRPCClient(conn)
  20. //传入上下文
  21. res, err := client.SayHi(context.Background(), &hello_grpc.Req{
  22. Message: "这是客户端发出的消息",
  23. })
  24. fmt.Println(res.GetMessage())
  25. }

两边运行起来就能看到效果了。