0

Go实现gRPC

 2 years ago
source link: https://blog.mailjob.net/posts/1433951833.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

Go实现gRPC

1月 16

go

go

评论 字数统计: 678(字) 阅读时长: 3(分)

Go原生方法实现RPC 文章中,我们通过原生的方法实现了 RPC 调用。但是大多是基于 protobuf 进行 RPC 的实现。

gRPC是Google公司基于Protobuf开发的跨语言的开源RPC框架。gRPC基于HTTP/2协议设计,可以基于一个HTTP/2链接提供多个服务,对于移动设备更加友好。本节将讲述gRPC的简单用法。

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

syntax = "proto3";
package pb;
option go_package="./pb;pb";

// 请求结构体
message HelloRequest {
  string res = 1;
}

// 返回结构体
message HelloResponse {
  int64 reply = 1;
}

server.go

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{}

// Length 和原生相比,这里的接收参数和返回参数都用的是proto生成的代码
func (h *HelloService) Length(res pb.HelloRequest, reply *pb.HelloResponse) error {
	reply.Reply = int64(len(res.Res))
	return nil
}

client_test.go

func TestClient(t *testing.T) {
	client, err := rpc.Dial("tcp", "127.0.0.1:8888")
	if err != nil {
		log.Fatal("dialing:", err)
	}

	// 定义请求和接受参数
	// 接收参数和返回参数都用的是proto生成的代码
	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

syntax = "proto3";
package pb;
option go_package="./pb;pb";

// 请求结构体
message HelloRequest {
  string res = 1;
}

// 返回结构体
message HelloResponse {
  int64 reply = 1;
}

// GRPC服务
service HelloService {
  // 计算字符串长度
  rpc Length(HelloRequest) returns (HelloResponse);
}

server.go

func main() {
	// 创建一个 grpc server
	grpcServer := grpc.NewServer()
	// 注册 grpc
	pb.RegisterHelloServiceServer(grpcServer, new(HelloService))

	lis, err := net.Listen("tcp", ":8888")
	if err != nil {
		log.Fatal(err)
	}
	// 监听端口上提供gRPC服务
	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

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())
}

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK