gRPC入门指南转载请联系Golang公众号。大家好,我是Seekload!我们将进行一段时间的gRPC之旅,欢迎入坑!学习gRPC所需的背景知识需要提前掌握:ProtocolBuffer协议;安装protoc和protoc-gen-go;这两部分知识就不详细讲解了,需要自己去学习。我们专注于gRPC。简介gRPC有四种数据交互模式:简单模式(SimpleRPC),客户端发起请求,等待服务端响应;服务器端流式RPC(Server-sidestreamingRPC),客户端向服务器发起请求,服务器返回一个连续的数据流响应;客户端流式RPC(Client-sidestreamingRPC),与服务器端流相反,客户端流式是客户端不断向服务器发送数据流,最后服务器返回一个Response;双向流式RPC(BidirectionalstreamingRPC),客户端和服务端可以同时向对方发送数据流,也可以同时接收数据;先说简单的,我们先来看简单模式的RPC,这种交互模式就是客户端请求一次,服务端响应一次,双方来来去去一次,就算单次通信结束了。创建并编译proto文件新建文件simple.protosyntax="proto3";packageproto;//定义发送请求信息messageSimpleRequest{//参数类型参数名标识号stringdata=1;}//定义响应信息messageSimpleResponse{int32code=1;stringvalue=2;}//定义我们的服务(可以定义多个服务,每个服务可以定义多个接口)serviceSimple{rpcGetSimpleInfo(SimpleRequest)returns(SimpleResponse){};}进入simple.proto所在目录位于,使用如下命令编译文件protoc--go_out=plugins=grpc:.simple.proto后,会生成simple.pb.go文件。文件的内容会在文章的后半部分进行整理。让我们先运行演示。创建服务器需要在服务器上实现GetSimpleInfo方法。packagemainimport("context"pb"go-grpc-example/1-simple_rpc/proto""google.golang.org/grpc""log""net")const(Addressstring=":8000"Networkstring="tcp")//定义我们的服务typeSimpleServicestruct{}//实现GetSimpleInfo方法func(s*SimpleService)GetSimpleInfo(ctxcontext.Context,req*pb.SimpleRequest)(*pb.SimpleResponse,error){data:=req.Datalog.Println("getfromclient:",data)resp:=&pb.SimpleResponse{Code:8888,Value:"grpc",}returnresp,nil}funcmain(){//1.监听端口监听,err:=net.Listen(Network,Address)iferr!=nil{log.Fatalf("net.listenerr:%v",err)}log.Println(Address,"netlistening...")//2。实例化gRPC服务器grpcServer:=grpc.NewServer()//3。注册我们实现的服务SimpleServicepb.RegisterSimpleServer(grpcServer,&SimpleService{})//4.启动gRPC服务器err=grpcServer.Serve(listener)iferr!=nil{log.Fatalf("grpcservererr:%v",err)}}服务端实现的主要流程,如上述代码所示:1->2->3->4。运行服务器:gorunserver.go输出::8000netlistening...创建客户端客户端可以直接调用服务器提供的服务(接口)packagemainimport("context"pb"go-grpc-example/1-simple_rpc/proto""google.golang.org/grpc""log")const(Addressstring=":8000")funcmain(){//1.连接conn,err:=grpc.Dial(Address,grpc.WithInsecure())iferr!=nil{log.Fatalf("dialconnerr:%v",err)}deferconn.Close()//2。创建grpc客户端client:=pb.NewSimpleClient(conn)//3.调用服务器提供的服务req:=pb.SimpleRequest{Data:"Hello,Server",}resp,err:=client.GetSimpleInfo(context.Background(),&req)iferr!=nil{log.Fatalf("resperr:%v",err)}log.Printf("getfromserver,code:%v,value:%v",resp.Code,resp.Value)}客户端实现的过程如上:1->2->3.运行客户端:gorunclient.go输出:getfromserver,code:8888,value:grpc成功调用服务端提供的方法并返回数据。simple.pb.go文件有详细解释。说完最基本的demo,我们来看一下编译后的simple.proto文件。熟悉这里的内容,有助于我们理解gRPC的调用过程。1、根据simple.proto定义的消息类型,会生成不同的struct。//定义发送请求信息typeSimpleRequeststruct{//参数类型参数名标识号datastring`protobuf:"bytes,1,opt,name=data,proto3"json:"data,omitempty"`}//定义响应信息typeSimpleResponsestruct{Codeint32`protobuf:"varint,1,opt,name=code,proto3"json:"code,omitempty"`Valuestring`protobuf:"bytes,2,opt,name=value,proto3"json:"value,omitempty"`}2.结构生成方法不同。func(m*SimpleRequest)Reset(){*m=SimpleRequest{}}func(m*SimpleRequest)String()string{returnproto.CompactTextString(m)}func(m*SimpleResponse)Reset(){*m=SimpleResponse{}}func(m*SimpleResponse)String()string{returnproto.CompactTextString(m)}func(m*SimpleResponse)GetCode()int32{ifm!=nil{returnm.Code}return0}func(m*SimpleResponse)GetValue()string{ifm!=nil{returnm.Value}return""}3.生成服务端和客户端的接口定义,如下://ClienttypeSimpleClientinterface{GetSimpleInfo(ctxcontext.Context,in*SimpleRequest,opts...grpc.CallOption)(*SimpleResponse,error)}//服务器类型SimpleServerinterface{GetSimpleInfo(context.Context,*SimpleRequest)(*SimpleResponse,error)}通信双方必须实现接口中定义的方法,细心的同学可以发现,客户端的方法GetSimpleInfo()其实已经自动生成了,客户端只需要调用即可。func(c*simpleClient)GetSimpleInfo(ctxcontext.Context,in*SimpleRequest,opts...grpc.CallOption)(*SimpleResponse,error){out:=new(SimpleResponse)err:=c.cc.Invoke(ctx,"/proto.Simple/GetSimpleInfo",in,out,opts...)iferr!=nil{returnil,err}returnout,nil}但是服务端方法需要自己实现,毕竟是service提供者,服务的具体逻辑由我们自己决定。4、最后还有注册服务功能。我们需要做的是自己定义一个struct对象,实现上面提到的SimpleServer接口,然后将该struct注册到gRPC服务中。funcRegisterSimpleServer(s*grpc.Server,srvSimpleServer){s.RegisterService(&_Simple_serviceDesc,srv)}总结本文主要介绍了gRPC的第一种交互方式——SimpleRPC,并演示了最基础的demo。你需要掌握以下两点:server和client的实现过程;simple.pb.go的内容;
