经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » 程序设计 » Go语言 » 查看文章
Go gRPC Hello World - it-world
来源:cnblogs  作者:it-world  时间:2019/11/15 8:58:46  对本文有异议

概述

开始 gRPC 了,这篇文章学习使用 gRPC,输出一个 Hello World。

    用 Go 实现 gRPC 的服务端。

    用 Go 实现 gRPC 的客户端。

gRPC 支持 4 类服务方法,咱们这次实现 单项 RPC 和 服务端流式 RPC。

四类服务方法

单项 RPC

服务端发送一个请求给服务端,从服务端获取一个应答,就像一次普通的函数调用。

rpc SayHello(HelloRequest) returns (HelloResponse){}

服务端流式 RPC

客户端发送一个请求给服务端,可获取一个数据流用来读取一系列消息。客户端从返回的数据流里一直读取直到没有更多消息为止。

rpc LotsOfReplies(HelloRequest) returns (stream HelloResponse){}

客户端流式 RPC

客户端用提供的一个数据流写入并发送一系列消息给服务端。一旦客户端完成消息写入,就等待服务端读取这些消息并返回应答。

  1. rpc LotsOfGreetings(stream HelloRequest) returns (HelloResponse) {}

 



双向流式 RPC

两边都可以分别通过一个读写数据流来发送一系列消息。这两个数据流操作是相互独立的,所以客户端和服务端能按其希望的任意顺序读写,例如:服务端可以在写应答前等待所有的客户端消息,或者它可以先读一个消息再写一个消息,或者是读写相结合的其他方式。每个数据流里消息的顺序会被保持。

  1. rpc BidiHello(stream HelloRequest) returns (stream HelloResponse){}

 



安装

安装 protobuf 编译器

  1. brew install protobuf

 



验证:

  1. protoc --version
  2. //输出:libprotoc 3.7.1

 



安装 Go protobuf 插件

  1. go get -u github.com/golang/protobuf/proto
  2. go get -u github.com/golang/protobuf/protoc-gen-go

 


安装 grpc-go

  1. go get -u google.golang.org/grpc

 




写个 Hello World 服务

    编写服务端 .proto 文件

    生成服务端 .pb.go 文件并同步给客户端

    编写服务端提供接口的代码

    编写客户端调用接口的代码

目录结构

    ├─ hello  -- 代码根目录    
    │  ├─ go_client    
    │     ├── main.go    
    │     ├── proto    
    │         ├── hello    
    │            ├── hello.pb.go    
    │  ├─ go_server    
    │     ├── main.go    
    │     ├── controller    
    │         ├── hello_controller    
    │            ├── hello_server.go    
    │     ├── proto    
    │         ├── hello    
    │            ├── hello.pb.go    
    │            ├── hello.proto

这样创建目录是为了 go_client 和 go_server 后期可以拆成两个项目。

编写服务端 hello.proto 文件

  1. syntax = "proto3"; // 指定 proto 版本
  2. package hello; // 指定包名
  3. // 定义 Hello 服务
  4. service Hello {
  5. // 定义 SayHello 方法
  6. rpc SayHello(HelloRequest) returns (HelloResponse) {}
  7. // 定义 LotsOfReplies 方法
  8. rpc LotsOfReplies(HelloRequest) returns (stream HelloResponse){}
  9. }
  10. // HelloRequest 请求结构
  11. message HelloRequest {
  12. string name = 1;
  13. }
  14. // HelloResponse 响应结构
  15. message HelloResponse {
  16. string message = 1;
  17. }

 



了解更多 Protobuf 语法,请查看:

  1. https://developers.google.com/protocol-buffers/

 



生成服务端 .pb.go

protoc -I . --go_out=plugins=grpc:. ./hello.proto

同时将生成的 hello.pb.go 复制到客户端一份。

查看更多命令参数,执行 protoc,查看 OPTION 。

编写服务端提供接口的代码

 

  1. // hello_server.go
  2. package hello_controller
  3. import (
  4. "fmt"
  5. "golang.org/x/net/context"
  6. "hello/go_server/proto/hello"
  7. )
  8. type HelloController struct{}
  9. func (h *HelloController) SayHello(ctx context.Context, in *hello.HelloRequest) (*hello.HelloResponse, error) {
  10. return &hello.HelloResponse{Message : fmt.Sprintf("%s", in.Name)}, nil
  11. }
  12. func (h *HelloController) LotsOfReplies(in *hello.HelloRequest, stream hello.Hello_LotsOfRepliesServer) error {
  13. for i := 0; i < 10; i++ {
  14. stream.Send(&hello.HelloResponse{Message : fmt.Sprintf("%s %s %d", in.Name, "Reply", i)})
  15. }
  16. return nil
  17. }
  18.  
  19. // main.go
  20. package main
  21. import (
  22. "log"
  23. "net"
  24. "hello/go_server/proto/hello"
  25. "hello/go_server/controller/hello_controller"
  26. "google.golang.org/grpc"
  27. )
  28. const (
  29. Address = "0.0.0.0:9090"
  30. )
  31. func main() {
  32. listen, err := net.Listen("tcp", Address)
  33. if err != nil {
  34. log.Fatalf("Failed to listen: %v", err)
  35. }
  36. s := grpc.NewServer()
  37. // 服务注册
  38. hello.RegisterHelloServer(s, &hello_controller.HelloController{})
  39. log.Println("Listen on " + Address)
  40. if err := s.Serve(listen); err != nil {
  41. log.Fatalf("Failed to serve: %v", err)
  42. }
  43. }

 



运行:

 

  1. go run main.go
  2. 2019/07/28 17:51:20 Listen on 0.0.0.0:9090

 


编写客户端请求接口的代码

  
 

  1. package main
    import (
  2. "hello/go_client/proto/hello"
  3. "io"
  4. "log"
  5. "golang.org/x/net/context"
  6. "google.golang.org/grpc"
  7. )
  8. const (
  9. // gRPC 服务地址
  10. Address = "0.0.0.0:9090"
  11. )
  12. func main() {
  13. conn, err := grpc.Dial(Address, grpc.WithInsecure())
  14. if err != nil {
  15. log.Fatalln(err)
  16. }
  17. defer conn.Close()
  18. // 初始化客户端
  19. c := hello.NewHelloClient(conn)
  20. // 调用 SayHello 方法
  21. res, err := c.SayHello(context.Background(), &hello.HelloRequest{Name: "Hello World"})
  22. if err != nil {
  23. log.Fatalln(err)
  24. }
  25. log.Println(res.Message)
  26. // 调用 LotsOfReplies 方法
  27. stream, err := c.LotsOfReplies(context.Background(),&hello.HelloRequest{Name: "Hello World"})
  28. if err != nil {
  29. log.Fatalln(err)
  30. }
  31. for {
  32. res, err := stream.Recv()
  33. if err == io.EOF {
  34. break
  35. }
  36. if err != nil {
  37. log.Printf("stream.Recv: %v", err)
  38. }
  39. log.Printf("%s", res.Message)
  40. }
  41. }

 



运行:

  1. go run main.go
  2. 2019/07/28 17:58:13 Hello World
  3. 2019/07/28 17:58:13 Hello World Reply 0
  4. 2019/07/28 17:58:13 Hello World Reply 1
  5. 2019/07/28 17:58:13 Hello World Reply 2
  6. 2019/07/28 17:58:13 Hello World Reply 3
  7. 2019/07/28 17:58:13 Hello World Reply 4
  8. 2019/07/28 17:58:13 Hello World Reply 5
  9. 2019/07/28 17:58:13 Hello World Reply 6
  10. 2019/07/28 17:58:13 Hello World Reply 7
  11. 2019/07/28 17:58:13 Hello World Reply 8

 

原文链接:http://www.cnblogs.com/it-3327/p/11861891.html

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号