当前位置:网站首页>[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
边栏推荐
- Turn off the xshell connection server and the running jar package will stop automatically
- 应广PMC131 SOP16 16pin八位单片机
- Easyai notes - machine learning
- No such file or directory: ‘/tmp/tmpxxx/tmpxxx.py‘
- Edgenext hit a mixed punch: a lightweight architecture integrating CNN and transformer
- Viewing technological changes through Huawei Corps (VI): smart highway
- Ora-19838 -- restore control files to the standby database
- Tips for self defined packaging of Yingguang SCM 003 burner
- Deep understanding of ThreadLocal
- Linux中,mysql设置job任务自动启动
猜你喜欢

【Zuul】com.netflix.zuul.exception.ZuulException: Hystrix Readed time out

MySQL --- 数据库的基本概念

Are you holding back on the publicity of the salary system for it posts such as testing, development, operation and maintenance?

RK1126平台项目总结

Modbus协议通信异常

Daily question - "number of daffodils"

透过华为军团看科技之变(六):智慧公路

Pfc232-sop8/14/16 should be wide-ranging and can be tape programmed with burning program

515. Find the maximum value in each tree row

使用Zadig从0到1搭建持续交付平台
随机推荐
[today in history] July 2: BitTorrent came out; The commercial system linspire was acquired; Sony deploys Playstation now
EdgeNeXt打出了一套混合拳:集CNN与Transformer于一体的轻量级架构
PFC232-SOP8/14/16应广一级可带烧录程序编带
Yingguang single chip microcomputer pms150/pmc150/pms150c consumer single chip microcomputer
How to download wechat payment certificate (API certificate)
php获取两个时间戳之间相隔多少天多少小时多少分多少秒
应广PMC131 SOP16 16pin八位单片机
Troubleshooting ideas that can solve 80% of faults
2 juillet: BitTorrent est sorti; L'acquisition du système commercial linspire; Sony Deployment PlayStation now
深入理解ThreadLocal
义隆EM78P153K DIP14单片机 MCU
Pms132b single chip microcomputer TWS digital tube Bluetooth charging chamber program development
515. Find the maximum value in each tree row
松翰SN8P2511 SOP8单片机 可代烧录 提供单片机方案开发 单片机解密
【网络是怎样连接的】第六章 请求到达服务器以及响应给客户端(完结)
easyAI笔记——深度学习
开发一个禁止删除namespace的控制器
把xshell连接服务器关掉,运行的jar包就自动停止的解决方案
详解Kubernetes网络模型
[nonlinear control theory]8_ Comparison of three robust controllers