RPC and Protobuf (3)

 

Introduction to Protobuf

  Protobuf is the abbreviation of Protocol Buffers. It is a data description language developed by Google. When it was opened in 2008, it was similar to XML, JSON and other description languages. It generated code and realized the function of structured data through the accompanying tools, but we are more concerned about What is Protobuf as the description language of the interface specification can be used as a basic tool for designing a secure cross-language RPC interface.

 

Getting started with Protobuf

  For those who have not used Protobuf, it is recommended to first understand the basic usage from the official website. Below we use Protobuf and RPC together to use Protobuf to ultimately ensure RPC interface specifications and security. The most basic data unit in Protobuf is message, which is similar to the existence of a structure in Go language. Message or other basic data type members can be nested in message.

 

Simple example

File Directory

---rpc_demo
│  client.go
│  go.mod
│  go.sum
│  service.go
│
└─proto
        hello.pb.go
        hello.proto

First create a proto directory under the project directory to store the proto file, and create a simple helllo.proto file:

syntax = "proto3"; // Declare syntax 

package proto; // You can customize 

message String according to your current package structure {// message keyword defines a String type, and there is only one value member of the string type, the member number The name is replaced by 1, which is why protobuf is small. Other data description languages ​​(json, xml) are identified by member names, and Portobuf is uniquely numbered, but it is not convenient to refer to 
    string value = 1; 
}

Enter the proto file directory and use the following command to generate the corresponding language script: protoc --go_out =. Hello.proto Generate the corresponding interface file. Then we can write the server and client code according to the generated go file, and write the server code first.

Note: The Protobuf core code is written in C ++, and the Go language is not supported in the official protobuf compiler. To generate the corresponding go code based on the hello.proto file, we need to download the corresponding plugin: go get github.com/ golang / protobuf / protoc-gen-go command installation, and finally through protoc --go_out =. hello.proto will generate the corresponding go file code

package main 

import ( 
   "log" 
   "net" 
   "net / rpc" 
   "rpc_protobuf / proto" 
) 

type HelloService struct {} 

// The specific method of implementing rpc service, please note that the accepted parameters must meet the requirements of the interface standards, because the current call All are structures, so the parameter 
func (p * HelloService) Hello (request * proto.String, reply * proto.String) error { 
   reply.Value = "hello:" + request.GetValue () 
   return nil 
} 

func main () { 
   // Register rpc service 
   rpc.RegisterName ("HelloService", new (HelloService)) 
   // Monitor tcp service 
   listenr, err: = net.Listen ("tcp", ": 1234") 
   if err! = nil { 
      log.Fatal ("Listen error:",err)
   }
   log.Println("service starting....")
   // Accept the relevant data request and connect it to the rpc service 
   conn, err: = listenr.Accept () 
   if err! = Nil { 
      log.Fatal ("Accept error", err) 
   } 

   rpc.ServeConn (conn ) 
}

  

Finally write the client code:

package main 

import ( 
   "fmt" 
   "log" 
   "net / rpc" 
   "rpc_protobuf / proto" 
) 

func main () { 
   // dial local 1234 port service 
   client, err: = rpc.Dial ("tcp", "localhost: 1234 ") 
   if err! = Nil { 
      log.Fatal (" TCP error: ", err) 
   } 

   // The parameters provided by the interface and the request parameters 
   var reply = & proto.String {} 
   var param = & proto.String { 
      Value : "Wang", 
   } 

   // Call remote service 
   err = client.Call ("HelloService.Hello", & param, & reply) 
   if err! = Nil { 
      log.Fatal (err) 
   } 

   fmt.Println(reply)
}

  

(Note: When using the Goland IDE, if we use the go mod, enable Go Moudle (vgo) integration and vendoring mode in the Go modules option in the setting need to be adjusted when there is a problem with the guide package)

We can start the server and the client to view the corresponding results. Here we simply use rpc and protobuf. Later we will introduce how to download protoc, protobuf, etc.

analysis:

Below we analyze the generated hello.pb.go file (interception part):

package proto // package name 
.... 

// implements a character type, 
type String struct { 
	Value string `protobuf:" bytes, 1, opt, name = value, proto3 "json:" value, generated from the proto file omitempty "` 
	XXX_NoUnkeyedLiteral struct {} `json:"-"` 
	XXX_unrecognized [] byte `json:"-"` 
	XXX_sizecache int32 `json:"-"` 
} 

.... 
// used for the value of the String type, In the service, the parameters can be obtained through this method, and each member will have the Get method 
func (m * String) GetValue () string { 
	if m! = Nil { 
		return m.Value 
	} 
	return "" 
}

  

True value

Above we have explained that combining rpc and protobuf through complex operations, we use protobuf to define input and output parameters and the structure of the implementation, but have you found that there is no service function in the generated hello.pb.go Only with some interface constraints, can we also define the services in RPC in Protobuf? In this way, we have realized the language-independent RPC service interface with Protobuf, which is the real value.

This belongs to the scope of Portobuf customization. If you are interested, you can read "Go Language Advanced Programming". Some of the previous articles are also taken from this book.

 

Guess you like

Origin www.cnblogs.com/double-W/p/12742411.html
RPC
RPC