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

posted @ 2022-05-15 18:20  RandySun  阅读(152)  评论(0编辑  收藏  举报