gRpc入门--简单的gRpc远程调用实验(go语言)

基本概念认识以及环境安装:

Rpc: rpc就是远程过程调用的意思。客户端调用一个方法,这个方法就像是本地方法,实际上是向远程服务端按照某种快速协议发送TCP请求,服务端计算完成后返回给客户端,客户端得到方法的调用结果
gRpc: 谷歌的一个RPC框架 下载地址
protobuf: 高效的传输协议,grpc采用的传输协议。类比于HTTP服务
protoc: 编译中间文件的编译器,是一个插件化的编译器 安装方法
protoc-gen-go: 使用protoc生成go文件所需要的编译器插件 安装方法

实验内容:
在本篇博客中,我们希望服务端提供一个两个数的加法服务,然后客户端提供两个数,再通过grpc调用获取结果。

服务端项目结构:

.
├── pbfiles
│ └── Prod.proto //中间文件,服务端客户端都要使用其编译而成的接口与方法
├── server.go //服务端主函数
└── services
├── Prod.pb.go //中间文件编译得到
└── ProdService.go //服务方法的定义文件

中间文件: Prod.proto
首先我们需要编写一个中间文件,中间文件中包含调用服务方法时所需要的请求结构request和响应结果response,以及服务的定义。Rpc远程调用的本质就是客户端通过网络调用服务端的一个结构的方法。我们把这个结构称为服务。例如服务端有一个结构struct A,包含方法func a,当把A注册到grpc服务后,客户端就可以拨号连接,再生成服务A对应的客户端,通过客户端调用方法a。调用时就需要传入request,然后接收response。

中间文件的语法学习见proto3语法

syntax="proto3";
package services;

message AddRequest{
  float add_a = 1;
  float add_b = 2;
}

message AddResponse{
  float add_rst = 1;
}

service AddService{
  rpc GetAddRst(AddRequest)returns(AddResponse);
}

中间文件编译得到 Prod.pb.go
在编写完中间文件后,我们在中间文件的目录下输入:
protoc --go_out=plugins=grpc:…/services Prod.proto

在servces目录下就会出现Prod.pb.go文件,这个文件是根据中间文件得到的go文件,其中包含了中间文件中的request,resonse,以及服务方法定义。还包括了grpc服务端和客户端需要用到的grpc方法。

文件内容太多,这里就不给出源代码了。

服务定义文件 ProdService.go
这里我们给出service AddService的方法定义:

package services

import (
"context"
)

type AddService struct {

}

func(x *AddService) GetAddRst(ctx context.Context, in *AddRequest) (*AddResponse, error) {
	return &AddResponse{AddRst: in.AddA + in.AddB},nil
}

服务端主函数:

package main

import (
	"google.golang.org/grpc"
	"net"
	"services"
)

func main(){
	rpcServer := grpc.NewServer()
	services.RegisterAddServiceServer(rpcServer,new(services.AddService))
	lis,_ := net.Listen("tcp",":8081")
	rpcServer.Serve(lis)
}

客户端项目结构:

.
├── main.go //客户端调用函数
└── services
└── Prod.pb.go //和服务端相同的中间文件编译文件

中间文件编译得到的Prod.pb.go
因为客户端我们也使用go语言调用,所以无需再进行编译中间文件,这里我们直接把服务端的Prod.pb.go文件复制过来即可。

main.go:

package main

import (
	"context"
	"fmt"
	"google.golang.org/grpc"
	"log"
	"services"
)

func main(){
	conn,err := grpc.Dial(":8081",grpc.WithInsecure())
	if err != nil{
		log.Fatal(err)
	}
	defer  conn.Close()

	prodClient := services.NewAddServiceClient(conn)
	prodRes,err := prodClient.GetAddRst(context.Background(),&services.AddRequest{AddA:2,AddB:3})
	if err != nil{
		log.Fatal(err)
	}
	fmt.Println(prodRes.AddRst)
}

你可能感兴趣的:(Go)