Gonet2 Game Server Framework parsing GRPC improved (5)

Source: Internet
Author: User
Tags lua sendmsg

The previous blog is about the basic use of the GRPC framework, assuming that the GRPC is only a few remote to send a few parameters, that and a normal HTTP request is not much different.

So today I'm going to take a look at the usage of GRPC advanced point.

Flow!

Streams can be divided into one-way and two-way depending on usage:

    • Unidirectional
      –client->server
      –server->client
    • Bidirectional
      –client<=>server

The following is a new sample, with three services using several flow service modes:
1. The number of references represents a piece of land. And the building that was returned was the one above the land.
2. The client keeps sending new points. Finally, a path is formed on the server and returned.
3. The client sends a new point, and the server returns a new point after the location operation.

syntax="proto3"Point{}Path{}message Ground{}message Construction{}{    // Server Side Stream    rpc ListConstructions(Ground) returns (stream Construction) {}    // Client Side Stream    Point) returns (Path){}    // Bidirectional streaming    OffsetPointPoint){}}

Execute the command to generate the code:

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

The generated code is too long. A section of the post, first the object definition part, here should be slightly simple:

 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. MarshaltypePointstruct{}func(M *point) Reset () {*m = point{}}func(M *point) String ()string{returnProto.compacttextstring (M)}func(*point) Protomessage () {}typePathstruct{}func(M *path) Reset () {*m = path{}}func(M *path) String ()string{returnProto.compacttextstring (M)}func(*path) Protomessage () {}typeGroundstruct{}func(M *ground) Reset () {*m = ground{}}func(M *ground) String ()string{returnProto.compacttextstring (M)}func(*ground) Protomessage () {}typeConstructionstruct{}func(M *construction) Reset () {*m = construction{}}func(M *construction) String ()string{returnProto.compacttextstring (M)}func(*construction) Protomessage () {}//Reference imports to suppress errors if they is not otherwise used.var_ Context. Contextvar_ Grpc. Clientconn

Several struct definitions of the generated go language correspond exactly to the 4 message definitions in the proto file. Compare the examples in the previous and the other, except for a few more objects. is not more complicated.

Skip over!

Service side

As soon as I saw this code, I was a little bit high. Just think about the previous sentence, "the same code." Look carefully, think that the difficulty is 5, not careful look, a bit on the blindfolded, the difficulty may be 8. So The roots are not difficult, but lazy to look at.

When I hit this, I found a very familiar piece of code, in the last paragraph of the generated file,

var _MapService_serviceDesc = grpc.ServiceDesc{}

Because this paragraph is the name of the service and the corresponding handler mapping, so. This all of a sudden have read 23 lines of code. But the difference is that this time is not an array of method, but streams array, very obviously, this time the service is the form of a stream. So Grpc is the method name of the service, as the name of the stream. For each stream, a handler method is generated accordingly:

    • _mapservice_listconstructions_handler
    • _mapservice_recordpath_handler
    • _mapservice_offset_handler

The above analysis shows that the approximate structure is still unchanged.

Look at the top two pieces of code that generate code. has been added to stare, not many explanations, I believe I have read the previous blog friend very easy to understand:

//Server APIForMapserviceservice//The service approach we're going to implement type mapserviceserver interface { listconstructions(*Ground,  Mapservice_listconstructionsserver) errorrecordpath (mapservice_recordpathserver)  ErrorOffset (mapservice_offsetserver) error}         We tell the GRPC framework that we implement the server-side object instance.func Registermapserviceserver(S *grpc.Server, SRVMapserviceserver) {s.Registerservice(&_mapservice_servicedesc, SRV)}
    • Service method One, the Server side one-way flow.
      Name implies. The service side to the client has a one-way channel, the entrance on the service side, the export in the client, and the service side will naturally have a data to this entry to write operations.

//Server Side Stream//RPC listconstructions (Ground) returns (stream construction) {}func_mapservice_listconstructions_handler (SRVInterface{}, Stream grpc. Serverstream) Error {m: =New(Ground)ifERR: = stream. Recvmsg (m); Err! =Nil{returnERR}returnSrv. (Mapserviceserver). Listconstructions (M, &mapservicelistconstructionsserver{stream})}typeMapservice_listconstructionsserverInterface{Send (*construction) error GRPC. Serverstream}typeMapservicelistconstructionsserverstruct{Grpc. Serverstream}func(x *mapservicelistconstructionsserver) Send (M *construction) error {returnX.serverstream.sendmsg (M)}

First, the _mapservice_listconstructions_handler method is called when the server receives the request, parses the data, and generates a mapservicelistconstructionsserver to provide the service.


The Mapservicelistconstructionsserver implements the Mapservice_listconstructionsserver interface, which includes a grpc encapsulated Serverstream. This is the entrance to the channel, and a send method for sending the message.

To create a server side one-way streaming service:

type mapServiceServer struct {        ...}func (s *mapServiceServer) ListConstructions(ground *Ground, stream MapService_ListConstructionsServer) error {    var constructions:= constructionsInGround(ground)    for _, construction := range constructions {        stream.Send(building)    }    return nil}
    • Service method Two, Client side one-way flow.
      The same is a channel between client & server, and this time the server receives the point data sent by the client.
func_mapservice_recordpath_handler (SRVInterface{}, Stream grpc. Serverstream) Error {returnSrv. (Mapserviceserver). Recordpath (&mapservicerecordpathserver{stream})}typeMapservice_recordpathserverInterface{sendandclose (*path) Error Recv () (*point, error) Grpc. Serverstream}typeMapservicerecordpathserverstruct{Grpc. Serverstream}func(x *mapservicerecordpathserver) Sendandclose (M *path) error {returnX.serverstream.sendmsg (M)}func(x *mapservicerecordpathserver) Recv () (*point, error) {m: =New(point)ifERR: = X.serverstream.recvmsg (M); Err! =Nil{return Nil, err}returnMNil}

The handler is used to receive client requests. Build the service object to do the detailed processing.


The service defines a flow object as a package. Receive method to receive the point data that the client keeps coming. The final return path is named Sendandclose because it is returned at once.

Create a client side one-way streaming service:

error {    for {        point, err := stream.Recv()        ifio.EOF {            return stream.SendAndClose(path)        else {            path.append(point)        }    }    returnnil}
    • Bidirectional flow
func_mapservice_offset_handler (SRVInterface{}, Stream grpc. Serverstream) Error {returnSrv. (Mapserviceserver). Offset (&mapserviceoffsetserver{stream})}typeMapservice_offsetserverInterface{Send (*point) Error Recv () (*point, error) Grpc. Serverstream}typeMapserviceoffsetserverstruct{Grpc. Serverstream}func(x *mapserviceoffsetserver) Send (M *point) error {returnX.serverstream.sendmsg (M)}func(x *mapserviceoffsetserver) Recv () (*point, error) {m: =New(point)ifERR: = X.serverstream.recvmsg (M); Err! =Nil{return Nil, err}returnMNil}

After reading the code in the face of unidirectional flow and bidirectional flow, this part seems to be understood at a glance!


To create a service method for a bidirectional flow:

error {    for {        point, err := stream.Recv()        ifio.EOF {            returnnil        }        ifnil {            return err        }        offsetPoint := offset(point)        ifnil {            return err        }    }}

As in the previous article. This blog mainly lies in the parsing of generated code, the above code. In addition to the proto build go file is real, the following code I have not run. Toss me with tomatoes!


Using two blog, basic to the GRPC framework has a understanding. Next, will return to the Gonet2 frame!

Look at the frame, how to use the GRPC!

Gonet2 Game Server Framework parsing GRPC improved (5)

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.