install
grpc在19年后go语言的编译插件改了,原本的– plugins = go的编译插件不能用了,必须使用新的编译插件。
安装相关插件
1 2
| go install google.golang.org/protobuf/cmd/protoc-gen-go@latest go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@latest
|
不出意外这些插件会出现在**$(GOPATH)**里面,但是不知道为什么我的GOPATH不起作用,后面把相关插件移动到了
一般而言GOPATH在home/go这个路径。
安装grpc
1 2 3 4 5
| cd /usr/local/Cellar/grpc/1.41.0/bin ls grpc_cli grpc_node_plugin grpc_python_plugin grpc_cpp_plugin grpc_objective_c_plugin grpc_ruby_plugin grpc_csharp_plugin grpc_php_plugin
|
进入它的bin目录就会发现带了很多编译插件,但是唯独没有golang的编译插件,这就是上面我说的golang插件改版,想cpp,python等安装grpc自带插件等语言编译方式与之前的编译方式相同,唯独golang的改了。
基础使用
protobuf相关
想要使用rpc调用,我们必须声明相关的service以及message,例如我们有如下这样一个proto文件
1 2 3 4 5 6 7 8 9 10 11 12 13
| syntax = "proto3";
option go_package = ",;" option go_package = "/proto" message info{ string time = 1; string info = 2; string name = 3; }
service say{ rpc SayHello(info) returns (info); }
|
以上我们声明了一个名为info的message和一个名为say的service。
其中say服务中声明语法是
1
| rpc func(param) returns (REST_T) // 关键字 函数名(函数参数) returns (返回类型)
|
函数参数和返回类型必须在proto文件中声明,不然proto文件使用时会因为找不到类型而报错。
server相关
我们先来看看如何起一个rpc服务,要想起一个rpc服务,首先我们要起一个tcp服务器,之后在注册相关的rpc服务器,然后监听即可。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38
| package main
import ( pb "SayHello/proto" "context" "fmt" "google.golang.org/grpc" "log" "net" "time" )
const port = ":9999" type routeGuideServer struct { pb.UnimplementedSayServer }
func (s routeGuideServer) SayHello(ctx context.Context, info *pb.Info) (*pb.Info, error) { cout := info.Name + info.Info + info.Time fmt.Println(cout) res := pb.Info{ Name: "server", Info: "hello client", Time: string(time.Time{}.Day()), } return &res,nil }
func main() { fmt.Println("hello world") listen, err := net.Listen("tcp",port) if err != nil { log.Fatalln(err.Error()) } grpcServer := grpc.NewServer() pb.RegisterSayServer(grpcServer,&routeGuideServer{}) grpcServer.Serve(listen) }
|
此时server的源码树目录如下
1 2 3 4 5 6 7 8
| . ├── go.mod ├── go.sum ├── main.go └── proto ├── message.pb.go ├── message.proto └── message_grpc.pb.go
|
Client相关
我们需要注册一个相关的grpc服务,之后链接到相关的服务器。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
| package main
import ( pb "SayHelloClient/proto" "context" "fmt" "google.golang.org/grpc" "log" "time" )
const serverAddr = ":9999" func Client() { conn,err := grpc.Dial(serverAddr,grpc.WithInsecure()) if err != nil { fmt.Println(err.Error()) } defer conn.Close() client := pb.NewSayClient(conn) info := pb.Info{ Name: "client", Info: "hello Server", Time: string(time.Time{}.Day()), } resp, err := client.SayHello(context.Background(),&info) if err != nil { log.Fatalln(err.Error()) } log.Printf("resp:%s",resp.GetName() + resp.Time + resp.Info) } func main() { fmt.Println("Hello world") Client() }
|
源码树目录
1 2 3 4 5 6 7 8
| . ├── go.mod ├── go.sum ├── main.go └── proto ├── message.pb.go ├── message.proto └── message_grpc.pb.go
|
编译
1 2
| proto --go-grpc_out=:. *.proto proto --go_out=:. *.proto
|
总结
用倒是不难用,就是grpc插件安装的时候坑比较多,之后还是流式服务,全双工服务,都大差不差这就不一一介绍了。