Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

How to use gRPC in Go

2025-01-16 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >

Share

Shulou(Shulou.com)06/01 Report--

This article mainly explains "how to use gRPC in Go". The content in the article is simple and clear, and it is easy to learn and understand. Please follow the editor's train of thought to study and learn "how to use gRPC in Go".

Getting started with Go GRPC 1, install the package

Grpc

The golang-grpc package provides a gRPC-related code base through which we can create a gRPC service or client, which needs to be installed first.

Go get-u google.golang.org/grpc

Protocol plug-in

To play gRPC, you can't do without proto files, so you need to install two packages to support the processing of protobuf files.

Go get-u github.com/golang/protobufgo get-u github.com/golang/protobuf/protoc-gen-go

Note: there is a protoc-gen-go.exe file under GOPATH/bin, but this is only a plug-in for protoc, it is not a protoc tool.

Protocol Buffers

Protocol Buffers is an extensible mechanism independent of programming language and platform, which is used to serialize structural data and is a data exchange format. GRPC uses protoc as a protocol processing tool.

When learning Go's gRPC, there is a hole, many articles do not talk about installing this, the command prompt does not exist protoc command.

After decompressing, copy the bin\ protoc.exe file inside, copy it to the GOPATH\ bin command, and put it with protoc-gen-go.exe.

test

After all the above is in place, we create a test.proto file in a new directory. The example is as follows:

Note: the protoc-3.15.6-win64\ include\ google\ protobuf directory also has many examples.

Syntax = "proto3"; / / package name package test;// specifies the directory to which the source code of the go language is output and the file name / / finally generates test.pb.go// in the test.proto directory or you can just fill in ". /" option go_package = ". /; test"; / / if you want to export other languages / / option csharp_package= "MyTest" Service Tester {rpc MyTest (Request) returns (Response) {}} / / function parameter message Request {string jsonStr = 1;} / the function returns the value message Response {string backJson = 1;}

Then, in the same directory as proto, execute the command to convert proto to the appropriate programming language file.

Protoc-go_out=plugins=grpc:. * .proto

You will find that the test.pb.go file is output in the current directory.

2GRPC server

Create a go program, copy test.pb.go to the main.go directory, and introduce grpc in main.go:

Import ("context", "fmt", "google.golang.org/grpc" / / test.pb.go default package name is package is main, there is no need to introduce "google.golang.org/grpc/reflection"log"net" here)

In test.pb.go, two Tester interfaces are generated. Let's take a look at the definitions of these two interfaces:

Type TesterServer interface {MyTest (context.Context, * Request) (* Response, error)} type TesterClient interface {MyTest (ctx context.Context, in * Request, opts... grpc.CallOption) (* Response, error)}

To implement the services in proto, we need to implement the TesterServer interface, and to write the client, we need to implement TesterClient.

Here we first implement Server.

/ used to implement Tester service type MyGrpcServer struct {} func (myserver * MyGrpcServer) MyTest (context context.Context, request * Request) (* Response, error) {fmt.Println ("received a grpc request, request parameters:", request) response: = Response {BackJson: `{"Code": 666}`} return & response, nil}

Then we create the gRPC service.

Func main () {/ / create Tcp connection listener, err: = net.Listen ("tcp", ": 8028") if err! = nil {log.Fatalf ("listening failed:% v") Err)} / / create gRPC service grpcServer: = grpc.NewServer () / / Tester register service implementer / / this function is in test.pb.go Automatically generate RegisterTesterServer (grpcServer, & MyGrpcServer {}) / / register the reflective service on the gRPC service / / func Register (s * grpc.Server) reflection.Register (grpcServer) err = grpcServer.Serve (listener) if err! = nil {log.Fatalf ("failed to serve:% v", err)} 3 GRPC client

Create a new go project and copy the test.pb.go to the main.go sibling directory, the main.go code:

Package mainimport ("bufio"context"google.golang.org/grpc"log"os") func main () {conn, err: = grpc.Dial ("127.0.0.1 log 8028", grpc.WithInsecure ()) if err! = nil {log.Fatal ("failed to connect to gPRC service," Err)} defer conn.Close () / / create gRPC client grpcClient: = NewTesterClient (conn) / / create request parameter request: = Request {JsonStr: `{"Code": 666}`,} reader: = bufio.NewReader (os.Stdin) for {/ / send request Call MyTest interface response, err: = grpcClient.MyTest (context.Background (), & request) if err! = nil {log.Fatal ("failed to send request because:", err)} log.Println (response) reader.ReadLine ()}} 4, compile and run

Because test.pb.go uses the package name main when it is created, multiple go files need to be compiled together at compile time:

Go build.\ main.go.\ test.pb.go

Then start server and client respectively, and each time the enter key is pressed in client, a gRPC message is sent.

At this point, we have learned a complete process of gRPC from the creation of the protocol to the creation of services and clients. Next, we will learn some related knowledge and learn some details.

5, other

Proto.Marshal can serialize the requested parameters, such as:

/ / create request parameters request: = Request {JsonStr: `{"Code": 666}`,} out,err:= proto.Marshal (& request) if err! = nil {log.Fatalln ("Failed to encode address book:", err)} if err:= ioutil.WriteFile ("E:/log.txt", out, 0644) Err! = nil {log.Fatalln ("Failed to write address book:", err)}

Proto.Unmarshal can be deserialized.

We can also customize how to serialize deserialized messages, code example:

B, err: = MarshalOptions {Deterministic: true} .Marshal (m) GRPCProtobuf buffer

Protobuf buffer is a data format, while Protobuf is the gRPC protocol, which needs to be distinguished here.

Protobuf buffer is an open source mechanism that Google uses to serialize structural session data. To define a protobuf buffer, you need to use a message definition.

Message Person {string name = 1; int32 id = 2; bool has_ponycopter = 3;}

Open source sees that each field has a number, and the = 1 is not an assignment, but a number. In a message, each field has a unique number, these numbers are used to identify fields in binary format (data transmission will be compressed, etc.), when the number range is 1-15:00, the storage number needs one byte, that is, no more than 15 fields in the message, 1-15 numbers are used to define frequent message elements. Of course, you can also use a number between 16 and 2047 as the number, which requires two bytes to store the number.

For details, you can refer to the official documentation:

Https://developers.google.com/protocol-buffers/docs/overview

Field Type

Instead of a detailed list of field types, readers can refer to the official documentation, which lists the commonly used data types:

Double, float, int32, int64, bool, string, bytes, enumeration.

Because gRPC needs to consider compatibility with C, C #, Java, Go, and so on, types in gRPC are not the same as related types in programming languages. These types are defined in gRPC, and if you want to convert to a type in a programming language, you need some conversion mechanism, which can be cumbersome.

Field rule

Each field can specify a rule that is identified by the rule at the beginning of defining the field type.

There are three rules:

Required: a properly formatted message must have exactly one of these fields, that is, a required field.

Optional: a well-formed message can contain zero or one of these fields (but not more than one, that is, the value is optional.

Repeated: in a well-formed message, this field can be repeated any number of times (including zero times), and the order of the repeated values is retained, indicating that the field can contain 0n elements.

Due to historical reasons, the field coding efficiency of repeated scalar number type is not high. The new code should use the special option [packed=true] to get more efficient coding. For example:

Repeated int32 samples = 4 [packed=true]

In the optional field optional, we can set a default value for it. If this field is not filled in when the message is delivered, the default value is used:

Optional int32 result_per_page = 3 [default = 10]; Protobuf

Next, we will introduce the protocol format (protobuf) of gRPC. Here is an example of the official document:

Syntax = "proto3"; package tutorial;import "google/protobuf/timestamp.proto"

Syntax specifies the version of the protocol

Package indicates the name of the .proto

The import keyword can introduce other .proto files into the current .proto, and the gRPC basic data type does not contain a time format, so you can introduce timestamp.proto.

Different programming languages introduce packages / libraries in different ways. C++ and C# both use namespaces to distinguish code locations; Java strictly distinguishes package names by directories and public classes; and go arbitrarily sets package names with a .go file.

Protoc was mentioned earlier, and you can convert the protocol file into specific code.

In order to be compatible with various programming languages, we set the _ package protocol, which allows you to set package / library names when generating code in different languages.

For example:

Option go_package = "Test"; / /... option csharp_package = "MyGrpc.Protos"; / / generate the namespace namespace MyGrpc.Protos {} option java_paclage = "MyJava.Protos"; / /. GRPC four service methods

In protobuf, you can define not only message but also streaming interfaces.

GRPC enables you to define four service methods:

Unary RPC, where the client sends a single request to the server and gets a single response, just like a normal function call. The things we mentioned above are all unitary gRPC.

Rpc SayHello (HelloRequest) returns (HelloResponse)

The server streams RPC, where the client sends a request to the server and fetches the stream to read back a series of messages. The client reads from the returned stream until there are no more messages. GRPC guarantees that messages are sorted in a single RPC call.

Client-> server-> return stream-> client-> receive stream

Rpc LotsOfReplies (HelloRequest) returns (stream HelloResponse)

The client stream RPC, where the client writes a sequence of messages and then sends them to the server again using the provided stream. After the client finishes writing the message, it waits for the server to read the message and return its response. GRPC once again guarantees the order of messages in a single RPC call.

Client-> send stream-> server-> receive stream->

Rpc LotsOfGreetings (stream HelloRequest) returns (HelloResponse)

Bi-directional streaming RPC, where both parties use read-write streams to send a series of messages. The two streams run independently, so the client and server can read and write in the order they like: for example, the server can wait to receive all client messages before writing the response, or it can read the message before writing it, or some other combination of read and write. The order of messages in each flow is preserved.

Rpc BidiHello (stream HelloRequest) returns (stream HelloResponse); compile proto

Previously, we used protoc to compile the .proto file into go. In order to support compilation to go, we need to install the protoc-gen-go plug-in, and C # can install the protoc-gen-zsharp plug-in.

It is important to note that it is not necessary to install protoc to convert .proto to a programming language.

For example, C # only needs to put the .proto file into the project, install a library through the package manager, and it will be automatically converted to the corresponding code.

Back to the point, let's talk about protoc's commands for compiling .proto files.

The common parameters of protoc are as follows:

-- proto_path=. # specify the path to the proto file and fill in. It means it's in the current directory-- go_out=.. # indicates the compiled file storage path; if you are compiling csharp, then-- csharp_out-- go_opt= {xxx.proto} = {xxx.proto path} # example:-- go_opt=Mprotos/bar.proto=example.com/project/protos/foo

The simplest compilation command:

Protoc-go_out=. * .proto

The {xxx} _ out instruction is required because you want to output specific programming language code.

The path to this output file is the path where the command is executed, and if we do not execute the command in the .proto file directory, the output code will not be in the same location. To solve this problem, we can use:

-- go_opt=paths=source_relative

If you execute the command elsewhere, the generated code will be placed in the same location as the .proto file.

Thank you for your reading, the above is the content of "how to use gRPC in Go". After the study of this article, I believe you have a deeper understanding of how to use gRPC in Go, and the specific use needs to be verified in practice. Here is, the editor will push for you more related knowledge points of the article, welcome to follow!

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Development

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report