grpc学习

2020-12-11  本文已影响0人  园游小会

grpc介绍

源于Google的内部RPC框架, 使用protobuf进行编码解码。

grpc的一些特点:

数据空间更小(protobuffer其数据格式紧密,没有多余的空格,括号,尖括号,key 等)

支持多种语言,通过 proto3 工具生成指定语言的数据结构、服务端接口以及客户端 Stub

支持相对复杂的数据格式

支持HTTP/2

性能相对更好,protobuffer + 二进制传输 + HTTP/2 。

grpc总共支持4种通信方式:

Simple RPC

简单rpc 这就是一般的rpc调用,一个请求对象对应一个返回对象 proto语法:

rpc simpleHello(Person) returns (Result) {}

Server-side streaming RPC

服务端流式rpc 一个请求对象,服务端可以传回多个结果对象

rpc serverStreamHello(Person) returns (stream Result) {}

Client-side streaming RPC

客户端流式rpc 客户端传入多个请求对象,服务端返回一个响应结果

rpc clientStreamHello(stream Person) returns (Result) {}

Bidirectional streaming RPC

双向流式rpc 结合客户端流式rpc和服务端流式rpc,可以传入多个对象,返回多个响应对象

rpc biStreamHello(stream Person) returns (stream Result) {}

grpc实现

Protobuf安装

Mac用户可以使用brew进行安装:

brew install protobuf

定义.proto 文件,  hello.proto 如下:

syntax="proto3";

packageproto;

// The request message containing the user's name.

messageHelloRequest{

stringname=1;

}

// The response message containing the greetings

messageHelloReply{

stringmessage=1;

}

// The greeting service definition.

serviceGreeter{

// Sends a greeting

rpcSayHello(HelloRequest)returns(HelloReply) {}

// Sends another greeting

rpcSayHelloAgain(HelloRequest)returns(HelloReply) {}

}

proto定义完之后,用protocol生成器生成一份go的代码,用来给server端和client端调用, 

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

生成的文件为hello.pb.go,包含几个部分:

方法出入参结构体以及序列化和反序列方法

注册出入参结构体的 init 方法

客户端存根结构体和接口以及实现

服务端结构体和接口以及一个空实现

stream 的 send 和 recv 结构体和接口以及实现

服务的一些描述

编写服务端代码:

服务端主要是定义一个结构体,实现pb.go接口

packageserver

import(

  "context"

  pb"github.com/goCode/rpc/grpc/proto"

)

typeHelloServerstruct{

}

func(s*HelloServer)SayHello(ctxcontext.Context,in*pb.HelloRequest) (*pb.HelloReply,error) {

  return&pb.HelloReply{Message:"Hello "+in.GetName()},nil

}

func(s*HelloServer)SayHelloAgain(ctxcontext.Context,in*pb.HelloRequest) (*pb.HelloReply,error) {

  return&pb.HelloReply{Message:"Hello again "+in.GetName()},nil

}

启动服务端

funcStartServer() {

  lis,err:=net.Listen("tcp","127.0.0.1:8091")

  iferr!=nil{

    log.Fatalf("failed to listen: %v",err)

  }

  //创建一个grpc服务器对象

  gRpcServer:=grpc.NewServer()

//注册grpc服务

  pb.RegisterGreeterServer(gRpcServer,&HelloServer{})

  gRpcServer.Serve(lis)

}

实现客户端

funcStartClient() {

  conn,err:=grpc.Dial("127.0.0.1:8091",grpc.WithInsecure())

  iferr!=nil{

    return

  }

  deferconn.Close()

  c:=pb.NewGreeterClient(conn)

  res,err:=c.SayHello(context.Background(),new(pb.HelloRequest),grpc.EmptyCallOption{})

  fmt.Println(res,err)

}

上一篇 下一篇

猜你喜欢

热点阅读