当前位置:网站首页>[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
proto
file , Definitionmessage
andservice
- Generated from compilation
pb.go
andgrpc.pb.go
The file implements the interface - The server registers the service and starts , The client establishes a connection to make method calls
边栏推荐
- [target tracking] | data set summary
- Easyai notes - deep learning
- win10 kms activator
- Alibaba cloud sub account - Permission Policy - full control permission granted to an account and an OSS bucket
- 每日一题——倒置字符串
- Microsoft LDAP 配置页中输入有效的用户名及密码,microsoft ldap 配置页中输入有效的用户名
- 【曆史上的今天】7 月 2 日:BitTorrent 問世;商業系統 Linspire 被收購;索尼部署 PlayStation Now
- 毕业总结
- 2 juillet: BitTorrent est sorti; L'acquisition du système commercial linspire; Sony Deployment PlayStation now
- Daily question - "number of daffodils"
猜你喜欢
一日2篇Nature!中科大校友段镶锋团队纳米材料新成果,曾是贝尔比奖章第三位华人得主...
finally详解
智能水电表能耗监测云平台
Virtual lab basic experiment tutorial -7 Polarization (1)
Solution to the problem that the easycvr kernel of intelligent video analysis platform cannot be started as a service
【Zuul】com.netflix.zuul.exception.ZuulException: Hystrix Readed time out
How to download wechat payment certificate (API certificate)
Modbus协议通信异常
自定义一个loading指令
[today in history] July 2: BitTorrent came out; The commercial system linspire was acquired; Sony deploys Playstation now
随机推荐
原装应广单片机 MCU芯片PMS152 SOP8封装 单片机开发
Pms150c Yingguang MCU development case
MySQL --- 數據庫的基本操作
【Zuul】com.netflix.zuul.exception.ZuulException: Hystrix Readed time out
应广单片机开发调试应注意的问题
应广PMC131 SOP16 16pin八位单片机
ORA-19838 -- 恢复控制文件到备库
JDBC
Simple understanding of cardinality sorting
外包干了五年,废了...
售价仅40元,树莓派Pico开发板加入WiFi模块,刚上市就脱销
Making tutorial of chicken feet with pickled peppers
MySQL --- 数据库的基本操作
Redisson 高性能 Redis 分布式锁源码分析
松翰SN8P2511 SOP8单片机 可代烧录 提供单片机方案开发 单片机解密
Edgenext hit a mixed punch: a lightweight architecture integrating CNN and transformer
应广单片机003烧录器自定义封装使用技巧
easyAI笔记——机器学习
977. Square of ordered array
PMS150C应广单片机开发案例