Go实现gRPC
go
go
字数统计: 710(字)
阅读时长: 3(分)
引言
在 Go原生方法实现RPC 文章中,我们通过原生的方法实现了 RPC 调用。但是大多是基于 protobuf 进行 RPC 的实现。
gRPC是Google公司基于Protobuf开发的跨语言的开源RPC框架。gRPC基于HTTP/2协议设计,可以基于一个HTTP/2链接提供多个服务,对于移动设备更加友好。本节将讲述gRPC的简单用法。
gRPC技术栈:

最底层为TCP或Unix Socket协议,在此之上是HTTP/2协议的实现,然后在HTTP/2协议之上又构建了针对Go语言的gRPC核心库。应用程序通过gRPC插件生产的Stub代码和gRPC核心库通信,也可以直接和gRPC核心库通信。
参考文献
protobuf入门学习:https://github.com/mailjobblog/dev_go/tree/master/220115_protobuf
Go原生RPC+protobuf代码下载:https://github.com/mailjobblog/dev_go/tree/master/220113_rpc/3.rpc_protobuf
gRPC代码下载:https://github.com/mailjobblog/dev_go/tree/master/220113_rpc/4.grpc
RPC实现
Go原生rpc+proto实现
代码实现
hello.proto
1 2 3 4 5 6 7 8 9 10 11 12 13
| syntax = "proto3"; package pb; option go_package="./pb;pb";
message HelloRequest { string res = 1; }
message HelloResponse { int64 reply = 1; }
|
server.go
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| func main() { rpc.Register(new(HelloService)) listener, err := net.Listen("tcp", ":8888") if err != nil { log.Fatal("ListenTCP error:", err) } for { conn, err := listener.Accept() if err != nil { log.Fatal("Accept error:", err) } go rpc.ServeConn(conn) } }
type HelloService struct{}
func (h *HelloService) Length(res pb.HelloRequest, reply *pb.HelloResponse) error { reply.Reply = int64(len(res.Res)) return nil }
|
client_test.go
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| func TestClient(t *testing.T) { client, err := rpc.Dial("tcp", "127.0.0.1:8888") if err != nil { log.Fatal("dialing:", err) }
res := pb.HelloRequest{Res: "test666"} var reply pb.HelloResponse
err = client.Call("HelloService.Length", res, &reply) if err != nil { log.Fatal(err) } fmt.Println(reply) }
|
gRPC实现
代码实现
hello.proto
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| syntax = "proto3"; package pb; option go_package="./pb;pb";
message HelloRequest { string res = 1; }
message HelloResponse { int64 reply = 1; }
service HelloService { rpc Length(HelloRequest) returns (HelloResponse); }
|
server.go
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| func main() { grpcServer := grpc.NewServer() pb.RegisterHelloServiceServer(grpcServer, new(HelloService))
lis, err := net.Listen("tcp", ":8888") if err != nil { log.Fatal(err) } grpcServer.Serve(lis) }
type HelloService struct { pb.UnimplementedHelloServiceServer }
func (h *HelloService) Length(ctx context.Context, res *pb.HelloRequest) (*pb.HelloResponse, error) { reply := &pb.HelloResponse{Reply: int64(len(res.Res))} return reply, nil }
|
client_test.go
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| func TestClient(t *testing.T) { conn, err := grpc.Dial("127.0.0.1:8888", grpc.WithTransportCredentials(insecure.NewCredentials())) if err != nil { log.Fatal(err) } defer conn.Close() client := pb.NewHelloServiceClient(conn)
reply, err := client.Length(context.Background(), &pb.HelloRequest{Res: "test123456"}) if err != nil { log.Fatal(err) } fmt.Println(reply.Reply) fmt.Println(reply.GetReply()) }
|