• grpc简单应用


    grpc简单应用

    一、gRPC主要有4种模式

    gRPC主要有4种请求和响应模式,分别是简单模式(Simple RPC)服务端流式(Server-side streaming RPC)客户端流式(Client-side streaming RPC)、和双向流式(Bidirectional streaming RPC)

    • 简单模式(Simple RPC):客户端发起请求并等待服务端响应。
    • 服务端流式(Server-side streaming RPC):客户端发送请求到服务器,拿到一个流去读取返回的消息序列。 客户端读取返回的流,直到里面没有任何消息。
    • 客户端流式(Client-side streaming RPC):与服务端数据流模式相反,这次是客户端源源不断的向服务端发送数据流,而在发送结束后,由服务端返回一个响应。
    • 双向流式(Bidirectional streaming RPC):双方使用读写流去发送一个消息序列,两个流独立操作,双方可以同时发送和同时接收。

    官方grpc-eg

    gRPC官方文档中文版

    源码

    二、新建proto文件

    主要是定义我们服务的方法以及数据格式,创建simple.proto文件。

    1.定义发送消息的信息

    message SimpleRequest{
        // 定义发送的参数,采用驼峰命名方式,小写加下划线,如:student_name
        string data = 1;//发送数据
    }
    

    2.定义响应信息

    message SimpleResponse{
        // 定义接收的参数
        // 参数类型 参数名 标识号(不可重复)
        int32 code = 1;  //状态码
        string value = 2;//接收值
    }
    

    3.定义服务方法Route

    // 定义我们的服务(可定义多个服务,每个服务可定义多个接口)
    service Simple{
        rpc Route (SimpleRequest) returns (SimpleResponse){};
    }
    

    4.编译proto文件

    syntax = "proto3";// 协议为proto3
    package proto;
    
    
    //  生成pb.go命令:  protoc -I ./ --go_out=plugins=grpc:.\01helloproto\proto\ .\01helloproto\proto\addressbook.proto
    
    option go_package = "./;proto";
    
    // 定义我们的服务(可定义多个服务,每个服务可定义多个接口)
    service Simple{
      rpc Route (SimpleRequest) returns (SimpleResponse){};
    }
    
    // 定义发送请求信息
    message SimpleRequest{
      // 定义发送的参数,采用驼峰命名方式,小写加下划线,如:student_name ===> studentName
      // 参数类型 参数名 标识号(1不可重复)
      string data = 1;
    }
    
    // 定义响应信息
    message SimpleResponse{
      // 定义接收的参数
      // 参数类型 参数名 标识号(1不可重复)
      int32 code = 1;
      string value = 2;
    }
    
    
    

    编译

    // 指令编译方法,进入go-grpc-example项目所在目录,运行
    go-grpc-example>  protoc -I ./ --go_out=plugins=grpc:.\02simplegrpc\proto\ .\02simplegrpc\proto\simple.proto
    

    image-20220504184421194

    二、创建Server端

    1.定义我们的服务,并实现Route方法

    package main
    
    import (
    	"context"
    	pb "go-grpc-example/02simpleGrpc/proto"
    	"log"
    	"net"
    
    	"google.golang.org/grpc"
    )
    
    /*
    @author RandySun
    @create 2022-03-27-20:03
    */
    
    // SimpleService 定义我们的服务
    type SimpleService struct {
    }
    
    // Route 实现Route方法
    func (s *SimpleService) Route(ctx context.Context, req *pb.SimpleRequest) (*pb.SimpleResponse, error) {
    	res := pb.SimpleResponse{
    		Code:  200,
    		Value: "hello " + req.Data,
    	}
    	return &res, nil
    }
    
    const (
    	// Address 监听地址
    	Address string = ":8001"
    	// NetWork 网络通信协议
    	NetWork string = "tcp"
    )
    
    func main() {
    	// 监听本地端口
    	listener, err := net.Listen(NetWork, Address)
    	if err != nil {
    		log.Fatalf("net.Listen err: %V", err)
    	}
    	log.Println(Address, "net.Listing...")
    	// 创建grpc服务实例
    	grpcServer := grpc.NewServer()
    	// 在grpc服务器注册我们的服务
    	pb.RegisterSimpleServer(grpcServer, &SimpleService{})
    
    	err = grpcServer.Serve(listener)
    	if err != nil {
    		log.Fatalf("grpcService.Serve err:%v", err)
    	}
    	log.Println("grpcService.Serve run success")
    }
    
    

    该方法需要传入RPC的上下文context.Context,它的作用结束超时取消的请求。更具体的说请参考该文章

    2.启动gRPC服务器

    package main
    
    import (
    	"context"
    	pb "go-grpc-example/02simpleGrpc/proto"
    	"log"
    
    	"google.golang.org/grpc"
    	"google.golang.org/grpc/credentials/insecure"
    )
    
    /*
    @author RandySun
    @create 2022-03-27-20:03
    */
    
    const (
    	// Address 监听地址
    	Address string = ":8001"
    	// NetWork 网络通信协议
    	NetWork string = "tcp"
    )
    
    func main() {
    	// 连接服务器
    	conn, err := grpc.Dial(Address, grpc.WithTransportCredentials(insecure.NewCredentials()))
    	if err != nil {
    		log.Fatalf("net.Connect connect: %v", err)
    	}
    	defer conn.Close()
    	// 建立gRpc连接
    	grpcClient := pb.NewSimpleClient(conn)
    
    	// 创建发送结构体
    	req := pb.SimpleRequest{
    		Data: "grpc",
    	}
    	// 调用 Route 方法 同时传入context.Context,  在有需要时可以让我们改变RPC的行为,比如超时/取消一个正在运行的RPC
    	res, err := grpcClient.Route(context.Background(), &req)
    	if err != nil {
    		log.Fatalf("Call Route err:%v", err)
    	}
    	// 打印返回直
    	log.Println("服务的返回响应data:", res)
    
    }
    
    
    go run server.go
    2022/03/27 20:14:10 :8001 net.Listing...
    

    image-20220504184930138

    三、创建Client端

    package main
    
    import (
    	"context"
    	"google.golang.org/grpc"
    	"google.golang.org/grpc/credentials/insecure"
    	pb "grpc/02simpleGrpc/proto"
    	"log"
    )
    
    /*
    @author RandySun
    @create 2022-03-27-20:03
    */
    
    const (
    	// Address 监听地址
    	Address string =":8001"
    	// NetWork 网络通信协议
    	NetWork string="tcp"
    )
    
    func main() {
    	// 连接服务器
    	conn, err := grpc.Dial(Address, grpc.WithTransportCredentials(insecure.NewCredentials()))
    	if err != nil {
    		log.Fatalf("net.Connect connect: %v", err)
    	}
    	defer conn.Close()
    	// 建立gRpc连接
    	grpcClient := pb.NewSimpleClient(conn)
    
    	// 创建发送结构体
    	req := pb.SimpleRequest{
    		Data: "grpc",
    	}
    	// 调用 Route 方法 同时传入context.Context,  在有需要时可以让我们改变RPC的行为,比如超时/取消一个正在运行的RPC
    	res, err := grpcClient.Route(context.Background(), &req)
    	if err != nil{
    		log.Fatalf("Call Route err:%v", err)
    	}
    	// 打印返回直
    	log.Println("服务的返回响应data:",res)
    
    }
    
    

    运行客户端

    go run client.go
    2022/03/27 20:20:39 服务的返回响应 data: code:200 value:"hello grpc"
    

    成功调用Server端的Route方法并获取返回的数据。

    image-20220327202937888

  • 相关阅读:
    HDOJ/HDU 2560 Buildings(嗯~水题)
    HDOJ/HDU 2555 人人都能参加第30届校田径运动会了(判断加排序~)
    POJ1703Find them, Catch them
    BZOJ2303: [Apio2011]方格染色
    BZOJ2809: [Apio2012]dispatching
    POJ1611The Suspects
    BZOJ2006: [NOI2010]超级钢琴
    BZOJ2288: 【POJ Challenge】生日礼物
    BZOJ1150: [CTSC2007]数据备份Backup
    洛谷P1316 P1824
  • 原文地址:https://www.cnblogs.com/randysun/p/16273924.html
Copyright © 2020-2023  润新知