go语言-gRPC简单实现

gRPC简单实现

0.RPC介绍

  • RPC时远程过程调用,是计算机通信协议。它可以通过运行的一台计算机的程序取调用另一个地址空间子程序。RPC是一CS模式。通过发送-接收进行交互
  • 而gRPC是一个开源的RPC框架,能够在任意环境中,最初谷歌进行开发,后来开源。它能够解决不同语言和环境间通信的复杂度。

1.安装

  • 安装gRPC(容易timeout...)

    go get -u google.golang.org/grpc
    
  • 安装Protocol BUffers

  • 安装protoc-gen-go

    go get -u github.com/golang/protobuf/protoc-gen-go
    
  • 需要注意:将下载protoc和protoc-gen-go添加到环境变量里面。

    vi ~/.bash_profile
    #添加环境变量:
    // protoc-gen-go 添加环境变量
    export PATH=$PATH:/Users/xujunkai/go/bin/
    // protocol buffers 添加环境变量
    export PATH=$PATH:/Users/xujunkai/pb_program/protoc-3.11.4-osx-x86_64/bin/
    # 刷新bash_
    source ~/.bash_profile
    

2.一个简单demo

  • 目录结果如下:

    ./gRPC_demo
    ├── go.mod
    ├── go.sum
    └── helloworld
        ├── client
        │   └── client.go
        │   ├── client.py
        ├── pb
        │   ├── helloworld.pb.go
        │   └── helloworld.proto
        └── server
            └── server.go
    
  • 首选需要编写proto代码,Protocol Buffers时一种与语言无关,平台无关的可扩展机制,用于序列化结构化数据。使用Protocol Buffers可以一次定义结构化的数据,然后可以使用特殊生成的源代码轻松地再各种数据流中使用各种语言编写和读取结构化数据。

  • helloworld.proto 编写:

    syntax = "proto3"; //声明版本, v3版本
    package pb; //声明包名
    
    // 定义一个服务
    service Greeter {
      // 方法名字叫:SayHello
      // HelloRequest --> HelloReply
      rpc SayHello (HelloRequest) returns (HelloReply) {}
    }
    
    // 请求消息
    message HelloRequest {
      string message = 1
    }
    
    // 响应消息
    message HelloReply {
      string message = 1
    }
    
  • 在gRPC_demo/helloworld/pb执行下列语句生成go语言源代码

    protoc -I helloworld/ helloworld/pb/helloworld.proto --go_out=plugins=grpc:helloworld
    				 //指定倒入文件路径
    											  //指定生成C++路径							 
    																											 // --go_out 生成go代码路径
    
  • 服务端:server

    package main
    
    import (
    	"fmt"
    	"net"
    
    	pb "gRPC_demo/helloworld/pb"
    	"golang.org/x/net/context"
    	"google.golang.org/grpc"
    	"google.golang.org/grpc/reflection"
    )
    
    type server struct{}
    
    func (s *server) SayHello(ctx context.Context, in *pb.HelloRequest) (*pb.HelloReply, error) {
    	return &pb.HelloReply{Message: "Hello " + in.Name}, nil
    }
    
    func main() {
    	// 监听本地的8972端口
    	lis, err := net.Listen("tcp", ":8972")
    	if err != nil {
    		fmt.Printf("failed to listen: %v", err)
    		return
    	}
    	s := grpc.NewServer() // 创建gRPC服务器
    	pb.RegisterGreeterServer(s, &server{}) // 在gRPC服务端注册服务
    
    	reflection.Register(s) //在给定的gRPC服务器上注册服务器反射服务
    	// Serve方法在lis上接受传入连接,为每个连接创建一个ServerTransport和server的goroutine。
    	// 该goroutine读取gRPC请求,然后调用已注册的处理程序来响应它们。
    	err = s.Serve(lis)
    	if err != nil {
    		fmt.Printf("failed to serve: %v", err)
    		return
    	}
    }
    
  • 编写客户端 client

    package main
    
    import (
    	"context"
    	"fmt"
    
    	pb "gRPC_demo/helloworld/pb"
    	"google.golang.org/grpc"
    )
    
    func main() {
    	// 连接服务器
    	conn, err := grpc.Dial(":8972", grpc.WithInsecure())
    	if err != nil {
    		fmt.Printf("faild to connect: %v", err)
    	}
    	defer conn.Close()
    
    	c := pb.NewGreeterClient(conn)
    	// 调用服务端的SayHello
    	r, err := c.SayHello(context.Background(), &pb.HelloRequest{Name: "q1mi"})
    	if err != nil {
    		fmt.Printf("could not greet: %v", err)
    	}
    	fmt.Printf("Greeting: %s !\n", r.Message)
    }
    
  • 先启动客户端,再启动服务端。

    // 打印结果
    Greeting:Helloqiqi ! 
    
    

猜你喜欢

转载自www.cnblogs.com/xujunkai/p/13378976.html
今日推荐