当前位置:网站首页>[golang | grpc] use grpc to realize simple remote call
[golang | grpc] use grpc to realize simple remote call
2022-07-02 17:57:00 【Field potato】
Environmental Science :
Golang: go1.18.2 windows/amd64
grpc: v1.47.0
protobuf: v1.28.0
Complete code :
https://github.com/WanshanTian/GolangLearning
cd GolangLearning/RPC/gRPC
1. brief introduction
gRPC It's based on C/S framework , Use protobuf A high-performance framework for remote procedure calls as a transport protocol , above 【Golang | gRPC】protocol buffer compiler\protoc Installation ,【Golang | gRPC】 Use protoc compile .proto file Separately protoc The installation and use of the compilation tool are described in detail , Let's go through a demo Specify gRPC Simple use
2. practice
There is one scenario below : The server stores the user's age information , Client input name , the RPC Get the corresponding age
2.1 proto file
2.1.1 newly build gRPC Folder , Use go mod init initialization , establish pb Folder , newly build query.proto file
syntax = "proto3";
package pb;
option go_package= ".;pb";
// Define the methods contained in the query service
service Query {
rpc GetAge (userInfo) returns (ageInfo) {}
}
// Request structure , Contains a name Field
message userInfo {
string name = 1;
}
// Respond to the structure of the application , Contains a age Field
message ageInfo {
int32 age = 1;
}
The server implements a query (Query) service , Contains a method GetAge; from Golang Level understanding , It's really just a Query Interface , Implemented a GetAge Method
2.1.2 stay .\gRPC\pb Use... In the directory protoc Tools to compile , stay pb Generate directly under the folder .pb.go and _grpc.pb.go file
protoc --go_out=./ --go-grpc_out=./ *.proto

2.2 pb.go and grpc.pb.go file
2.2.1 see query_grpc.pb.go Generated in about QueryServer The definition of
type QueryServer interface {
GetAge(context.Context, *UserInfo) (*AgeInfo, error)
mustEmbedUnimplementedQueryServer()
}
// UnimplementedQueryServer must be embedded to have forward compatible implementations.
type UnimplementedQueryServer struct {
}
func (UnimplementedQueryServer) GetAge(context.Context, *UserInfo) (*AgeInfo, error) {
return nil, status.Errorf(codes.Unimplemented, "method GetAge not implemented")
}
func (UnimplementedQueryServer) mustEmbedUnimplementedQueryServer() {
}
QueryServer It is based on proto Defined in the file service Query{} Generated interfaces ,GetAge Our definition is ,mustEmbedUnimplementedQueryServer() The method is protoc Self compiled (https://github.com/grpc/grpc-go/issues/3669 Here's a detailed discussion , Through protoc Compile time , You can also add parameters to cancel this method ,protoc --go_out=./ --go-grpc_out=require_unimplemented_servers=false:./ *.proto)
2.2.2 see pb.go About China UserInfo and AgeInfo The definition of
type UserInfo struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
}
func (x *UserInfo) GetName() string {
if x != nil {
return x.Name
}
return ""
}
type AgeInfo struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Age int32 `protobuf:"varint,1,opt,name=age,proto3" json:"age,omitempty"`
}
func (x *AgeInfo) GetAge() int32 {
if x != nil {
return x.Age
}
return 0
}
UserInfo and AgeInfo The first three fields of the structure are temporarily unavailable , By means of Get... You can get the value of the custom field
2.3 Server side
stay gRPC New under the directory Server Folder , newly build main.go file
2.3.1 So let's go through Query This structure is specifically implemented QueryServer Interface
var userinfo = map[string]int32{
"foo": 18,
"bar": 20,
}
// Query Realized QueryServer Interface
type Query struct {
pb.UnimplementedQueryServer // By default, it is realized through the nesting of structures mustEmbedUnimplementedQueryServer() This method , see 2.2.1
}
func (q *Query) GetAge(ctx context.Context, info *pb.UserInfo) (*pb.AgeInfo, error) {
age := userinfo[info.GetName()]
var res = new(pb.AgeInfo)
res.Age = age
return res, nil
}
2.3.2 The service registers and starts
func main() {
// establish socket Monitor
listener, err := net.Listen("tcp", ":1234")
if err != nil {
log.Panic(err)
}
// new One gRPC The server , Used to register services
grpcserver := grpc.NewServer()
// Registration service method
pb.RegisterQueryServer(grpcserver, new(Query))
// Turn on gRPC service
err = grpcserver.Serve(listener)
if err != nil {
log.Panic(err)
}
}
Use RegisterQueryServer This method is directed to gRPC Register services in the server . Here are two services , It's easy to confuse concepts , One is gRPC service ( Used to monitor , Complete some network 、 Routing and so on ), One is business level services ( These services can be understood as interfaces containing certain methods , Used to call the client )
2.4 client
stay gRPC New under the directory Client Folder , newly build main.go file
2.4.1 First establish a connection without authentication , Generate Client, Then make a method call
package main
import (
"context"
"fmt"
"google.golang.org/grpc"
"google.golang.org/grpc/credentials/insecure"
"log"
"wanshantian/grpc/pb"
)
func main() {
// Establish a connection without authentication
conn, err := grpc.Dial(":1234", grpc.WithTransportCredentials(insecure.NewCredentials()))
if err != nil {
log.Panic(err)
}
defer conn.Close()
client := pb.NewQueryClient(conn)
//RPC Method call
age, _ := client.GetAge(context.Background(), &pb.UserInfo{
Name: "foo"})
fmt.Println(age)
}
notes :
- Use
grpc.WithTransportCredentials(insecure.NewCredentials())Establish a connection without authentication - Use
client := pb.NewQueryClient(conn)Generate gRPC client
The operation results are as follows :
age:18
3 summary
- First create
protofile , Definitionmessageandservice - Generated from compilation
pb.goandgrpc.pb.goThe file implements the interface - The server registers the service and starts , The client establishes a connection to make method calls
边栏推荐
- 原装应广单片机 MCU芯片PMS152 SOP8封装 单片机开发
- Solution to the problem that the easycvr kernel of intelligent video analysis platform cannot be started as a service
- finally详解
- [nonlinear control theory]7_ High gain and High Frequency
- [how to connect the network] Chapter 5 explore the server
- [target tracking] | data set summary
- 自定义一个loading指令
- win10 kms activator
- wait_ for_ Gap -- restore archive from primary archive to secondary Archive
- EdgeNeXt打出了一套混合拳:集CNN与Transformer于一体的轻量级架构
猜你喜欢

售价仅40元,树莓派Pico开发板加入WiFi模块,刚上市就脱销

PFC232-SOP8/14/16应广一级可带烧录程序编带

一日2篇Nature!中科大校友段镶锋团队纳米材料新成果,曾是贝尔比奖章第三位华人得主...

From a professional background, I can't get into a small company for interview

Easyswoole3.2 restart failed

MySQL进阶-事务及索引

win10 kms activator
![List summation [dummy+ tail interpolation + function processing list reference common pit]](/img/08/30e8ca2376104d648a82dca8a72c42.png)
List summation [dummy+ tail interpolation + function processing list reference common pit]

Does pytorch support 32 bits?

详解Kubernetes网络模型
随机推荐
原厂原装 应广单片机PMS134方案开发应用案例
Yingguang MCU development case
In Linux, MySQL sets the job task to start automatically
义隆EM78P153K DIP14单片机 MCU
Yingguang single chip microcomputer development specification pmc131 with AD chip to detect battery voltage single chip microcomputer sop8/14
[target tracking] | data set summary
wait_for_gap -- 从主库归档备库恢复归档
【网络是怎么连接的】第四章 探索接入网和网络运营商
每日一题——“水仙花数”
原装应广单片机 MCU芯片PMS152 SOP8封装 单片机开发
Ora-19838 -- restore control files to the standby database
Development and application case of pms134 scheme of Yingguang single chip microcomputer with original packaging
Daily question - "number of daffodils"
MySQL安装与配置
应广单片机003烧录器自定义封装使用技巧
Editor编辑器扩展在Scene View添加按钮和logo
体验一下阿里云文字识别OCR
PFC232-SOP8/14/16应广一级可带烧录程序编带
Problems needing attention in the development and debugging of Yingguang single chip microcomputer
Huimang micro IO MCU ft60f010a-urt