Gonet2 Game Server Framework Parsing GRPC Introduction (4)

Source: Internet
Author: User

Gonet2, a lot of use of the GRPC, and I am not familiar with this, so take some time to understand. Of course, the environment I have well, here is just how to use the code, the environment, the Internet should be quite a lot. But with GRPC to use the scientific way to surf the internet, this to my fellow citizens of the Huaxia, should be no stranger.

Remote Call, at first I think very complex, but really understand that, nothing more than, server side provides a root interface, the format of the public call to transmit data, the client side in accordance with this rule, call the method provided by the interface.

The problem is, since it's remote, it's definitely a cross-process, or even a cross-computer. So it can be called remotely via network transmission. such as TCP/IP, HTTP.

Grpc is one of the remote calling frameworks, where the transport is defined by the HTTP2 protocol, using the interface Description Language Proto3 to define the service interface, as well as the data structure. Previous Proto2, but Proto3 is the latest, grammatical structure has a small difference.

Since there is a call B this process, there is a network protocol, that for the interface, there will definitely be a client, and the server. The server handles the request and the client goes to invoke the interface. So, so much nonsense, let's take a look at one of the simplest Hello World interface definitions.

// 没得更简单了,我试着用int32来做参数和返回值,// 可是结果确是必须为message类型.// message是grpc的封装类型,相当于go语言的struct或java的class.syntax="proto3";message Req{}message Res{}service HelloService {    rpc Hello(Req) returns (Res) {}}

Generated code, a little frightened of my feeling! I wrote 6 lines to generate so much! First put the complete code on the post, and then we take a little apart to see, if scared, skip first.

//Code generated by protoc-gen-go.//Source:test.proto// do not edit!/*package test is a generated protocol the buffer package. It is generated from these files:test.protoIt have these top-level messages:req res*/ PackageTestImportProto"Github.com/golang/protobuf/proto"Import(Context"Golang.org/x/net/context"Grpc"Google.golang.org/grpc")//Reference imports to suppress errors if they is not otherwise used.var_ = Proto. MarshaltypeReqstruct{}func(M *req) Reset () {*m = req{}}func(M *req) String ()string{returnProto.compacttextstring (M)}func(*req) Protomessage () {}typeResstruct{}func(M *res) Reset () {*m = res{}}func(M *res) String ()string{returnProto.compacttextstring (M)}func(*res) Protomessage () {}//Reference imports to suppress errors if they is not otherwise used.var_ Context. Contextvar_ Grpc. Clientconn//Client API for HelloService servicetypeHelloserviceclientInterface{Hello (CTX context. Context, in *req, opts ... grpc. Calloption) (*res, error)}typeHelloserviceclientstruct{cc *GRPC. Clientconn}funcNewhelloserviceclient (cc *grpc. Clientconn) Helloserviceclient {return&HELLOSERVICECLIENT{CC}}func(c *helloserviceclient) Hello (CTX context. Context, in *req, opts ... grpc. Calloption) (*res, error) {out: =New(Res) Err: = Grpc. Invoke (CTX,"/. Helloservice/hello ", in, out, c.cc, opts ...)ifErr! =Nil{return Nil, err}returnOutNil}//Server API for HelloService servicetypeHelloserviceserverInterface{Hello (context. Context, *req) (*res, error)}funcRegisterhelloserviceserver (S *grpc. Server, SRV helloserviceserver) {s.registerservice (&_helloservice_servicedesc, SRV)}func_helloservice_hello_handler (SRVInterface{}, CTX context. Context, codec Grpc. Codec, buf []byte) (Interface{}, error) {in: =New(REQ)ifERR: = codec. Unmarshal (buf, in); Err! =Nil{return Nil, err} out, err: = srv. (Helloserviceserver). Hello (CTX, in)ifErr! =Nil{return Nil, err}returnOutNil}var_helloservice_servicedesc = Grpc. servicedesc{ServiceName:". HelloService ", Handlertype: (*helloserviceserver) (Nil), Methods: []grpc. methoddesc{{MethodName:"Hello", Handler: _helloservice_hello_handler,},}, Streams: []grpc. streamdesc{},}

Take a closer look, and the notes are pretty clear. My personal feeling is, to play a metaphor, the same code, look carefully, feel the difficulty is 5, do not look carefully, a bit on the mask, the difficulty may be 8.

The above analysis of RPC calls, there are server and client, there is a data format for communication, in this raw component is just the three parts. (Actually, I read this grpc first, and then analyze the theory in turn, anyway!) )

Service side

First look at the server section, I added some comments, explained in more detail the role of each part, is entirely to take care of the novice, and like me, do not like to look at the code carefully.

//HelloService service Interface Definition//By implementing this interface to define the specific content of the service method Hello, this is the server SidetypeHelloserviceserverInterface{Hello (context. Context, *req) (*res, error)}//implemented the above service-side (Server Side)//Call this method to tell the GRPC framework who our server object is. funcRegisterhelloserviceserver (S *grpc. Server, SRV helloserviceserver) {s.registerservice (&_helloservice_servicedesc, SRV)}//This is the Service interface agent, is added a layer of packaging meaning,//The data from the network is byte[], here to parse into a Req object,//Then go to call our server side's Hello method. func_helloservice_hello_handler (SRVInterface{}, CTX context. Context, codec Grpc. Codec, buf []byte) (Interface{}, error) {in: =New(REQ)ifERR: = codec. Unmarshal (buf, in); Err! =Nil{return Nil, err} out, err: = srv. (Helloserviceserver). Hello (CTX, in)ifErr! =Nil{return Nil, err}returnOutNil}//This variable is the description object of the service. Defines the name, type, method, etc. of the service. //In the Registerhelloserviceserver method, this variable is passed to the GRPC frame. var_helloservice_servicedesc = Grpc. servicedesc{ServiceName:". HelloService ", Handlertype: (*helloserviceserver) (Nil), Methods: []grpc. methoddesc{//Service method Array{MethodName:"Hello", Handler: _helloservice_hello_handler,},}, Streams: []grpc. streamdesc{},}

The first step-define and implement the service:

type helloServiceServer struct {}func (s *helloServiceServer) Hello(ctx context.Context, req *test.Req) (*test.Res, error) {        fmt.Println("Hello")        return &test.Res{}, nil}

Step two-turn on network services:

// 监听端口lis, err := net.Listen("tcp", fmt.Sprintf(":%d", *port))if err != nil {        log.Fatalf("failed to listen: %v", err)}// 创建grpc实例grpcServer := grpc.NewServer()// 注册helloService服务test.RegisterHelloServiceServer(grpcServer, &helloServiceServer{})// 启动服务grpcServer.Serve(lis)

In fact, it is not much worse than an HTTP service, listening to a port, then registering the service, and then waiting to receive the request. If you take a closer look at methods inside is an array, here to Hello and _helloservice_hello_handle do a mapping, should be a routing function, plainly, is based on the name of the request, call the appropriate method to handle.

Client
//Client interface, which defines the method of servicetypeHelloserviceclientInterface{Hello (CTX context. Context, in *req, opts ... grpc. Calloption) (*res, error)}//This is the implementation of client sidetypeHelloserviceclientstruct{cc *GRPC. Clientconn}//Factory method, get a client instance. //Our code is going to invoke the remote service through this instance. funcNewhelloserviceclient (cc *grpc. Clientconn) Helloserviceclient {return&HELLOSERVICECLIENT{CC}}//Client side service method encapsulation. //We call this method, here Grpc to wrap our parameters and send them out. //As a client, just call on the finished, is not very convenient! func(c *helloserviceclient) Hello (CTX context. Context, in *req, opts ... grpc. Calloption) (*res, error) {out: =New(Res) Err: = Grpc. Invoke (CTX,"/. Helloservice/hello ", in, out, c.cc, opts ...)ifErr! =Nil{return Nil, err}returnOutNil}

Above is the generated go language code, inside I added a comment. I believe you have seen it and understand, do not understand the words are not good for me to express. Next look at how to use:

// 先连接到服务器conn, err := grpc.Dial(*serverAddr)if err != nil {    ...}defer conn.Close()// 通过工厂方法得到一个客户端对象client := test.NewHelloServiceClient(conn)// 调用client.Hello(context.Background(), &test.Req{})

* Please note that the above code, in addition to Proto is my own generation, the following test code I have not run, said the analysis.

Copyright NOTICE: This article for Bo Master original article, without Bo Master permission not reproduced.

Gonet2 Game Server Framework Parsing GRPC Introduction (4)

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.