Golang中grpc怎么用

发布时间:2021-12-15 09:27:50 作者:小新
来源:亿速云 阅读:219

Golang中gRPC怎么用

1. 什么是gRPC?

gRPC是一个高性能、开源的通用RPC框架,由Google开发。它基于HTTP/2协议,使用Protocol Buffers(简称Protobuf)作为接口定义语言(IDL),支持多种编程语言。gRPC的主要特点包括:

2. gRPC的核心概念

2.1 Protocol Buffers

Protocol Buffers(简称Protobuf)是Google开发的一种轻量级、高效的结构化数据序列化格式。它比XML和JSON更小、更快、更简单。Protobuf使用.proto文件定义数据结构,然后通过编译器生成对应语言的代码。

2.2 服务定义

在gRPC中,服务通过.proto文件定义。一个服务可以包含多个方法,每个方法可以定义请求和响应的消息类型。

2.3 四种服务方法

gRPC支持四种类型的服务方法:

  1. Unary RPC:客户端发送一个请求,服务器返回一个响应。
  2. Server Streaming RPC:客户端发送一个请求,服务器返回一个流式响应。
  3. Client Streaming RPC:客户端发送一个流式请求,服务器返回一个响应。
  4. Bidirectional Streaming RPC:客户端和服务器都可以发送流式请求和响应。

3. 在Golang中使用gRPC

3.1 安装gRPC和Protobuf编译器

首先,我们需要安装gRPC和Protobuf编译器。

# 安装gRPC
go get -u google.golang.org/grpc

# 安装Protobuf编译器
go get -u github.com/golang/protobuf/protoc-gen-go

3.2 定义服务

创建一个hello.proto文件,定义一个简单的服务:

syntax = "proto3";

package hello;

service Greeter {
  rpc SayHello (HelloRequest) returns (HelloResponse);
}

message HelloRequest {
  string name = 1;
}

message HelloResponse {
  string message = 1;
}

3.3 生成代码

使用protoc编译器生成Golang代码:

protoc --go_out=plugins=grpc:. hello.proto

这将生成hello.pb.go文件,其中包含客户端和服务端的代码。

3.4 实现服务端

创建一个server.go文件,实现服务端逻辑:

package main

import (
	"context"
	"log"
	"net"

	"google.golang.org/grpc"
	pb "path/to/your/proto/package"
)

type server struct{}

func (s *server) SayHello(ctx context.Context, in *pb.HelloRequest) (*pb.HelloResponse, error) {
	return &pb.HelloResponse{Message: "Hello " + in.Name}, nil
}

func main() {
	lis, err := net.Listen("tcp", ":50051")
	if err != nil {
		log.Fatalf("failed to listen: %v", err)
	}
	s := grpc.NewServer()
	pb.RegisterGreeterServer(s, &server{})
	if err := s.Serve(lis); err != nil {
		log.Fatalf("failed to serve: %v", err)
	}
}

3.5 实现客户端

创建一个client.go文件,实现客户端逻辑:

package main

import (
	"context"
	"log"
	"time"

	"google.golang.org/grpc"
	pb "path/to/your/proto/package"
)

func main() {
	conn, err := grpc.Dial("localhost:50051", grpc.WithInsecure(), grpc.WithBlock())
	if err != nil {
		log.Fatalf("did not connect: %v", err)
	}
	defer conn.Close()
	c := pb.NewGreeterClient(conn)

	ctx, cancel := context.WithTimeout(context.Background(), time.Second)
	defer cancel()
	r, err := c.SayHello(ctx, &pb.HelloRequest{Name: "World"})
	if err != nil {
		log.Fatalf("could not greet: %v", err)
	}
	log.Printf("Greeting: %s", r.Message)
}

3.6 运行服务端和客户端

首先运行服务端:

go run server.go

然后运行客户端:

go run client.go

你应该会看到客户端输出:

Greeting: Hello World

4. 流式RPC

4.1 Server Streaming RPC

hello.proto中添加一个Server Streaming RPC方法:

service Greeter {
  rpc SayHello (HelloRequest) returns (HelloResponse);
  rpc SayHelloStream (HelloRequest) returns (stream HelloResponse);
}

更新server.go实现流式响应:

func (s *server) SayHelloStream(in *pb.HelloRequest, stream pb.Greeter_SayHelloStreamServer) error {
	for i := 0; i < 5; i++ {
		if err := stream.Send(&pb.HelloResponse{Message: "Hello " + in.Name}); err != nil {
			return err
		}
		time.Sleep(time.Second)
	}
	return nil
}

更新client.go处理流式响应:

stream, err := c.SayHelloStream(ctx, &pb.HelloRequest{Name: "World"})
if err != nil {
	log.Fatalf("could not greet: %v", err)
}
for {
	msg, err := stream.Recv()
	if err == io.EOF {
		break
	}
	if err != nil {
		log.Fatalf("could not receive: %v", err)
	}
	log.Printf("Greeting: %s", msg.Message)
}

4.2 Client Streaming RPC

hello.proto中添加一个Client Streaming RPC方法:

service Greeter {
  rpc SayHello (HelloRequest) returns (HelloResponse);
  rpc SayHelloStream (HelloRequest) returns (stream HelloResponse);
  rpc SayHelloClientStream (stream HelloRequest) returns (HelloResponse);
}

更新server.go实现流式请求处理:

func (s *server) SayHelloClientStream(stream pb.Greeter_SayHelloClientStreamServer) error {
	var names []string
	for {
		req, err := stream.Recv()
		if err == io.EOF {
			return stream.SendAndClose(&pb.HelloResponse{Message: "Hello " + strings.Join(names, ", ")})
		}
		if err != nil {
			return err
		}
		names = append(names, req.Name)
	}
}

更新client.go发送流式请求:

stream, err := c.SayHelloClientStream(ctx)
if err != nil {
	log.Fatalf("could not greet: %v", err)
}
for _, name := range []string{"Alice", "Bob", "Charlie"} {
	if err := stream.Send(&pb.HelloRequest{Name: name}); err != nil {
		log.Fatalf("could not send: %v", err)
	}
}
reply, err := stream.CloseAndRecv()
if err != nil {
	log.Fatalf("could not receive: %v", err)
}
log.Printf("Greeting: %s", reply.Message)

4.3 Bidirectional Streaming RPC

hello.proto中添加一个Bidirectional Streaming RPC方法:

service Greeter {
  rpc SayHello (HelloRequest) returns (HelloResponse);
  rpc SayHelloStream (HelloRequest) returns (stream HelloResponse);
  rpc SayHelloClientStream (stream HelloRequest) returns (HelloResponse);
  rpc SayHelloBidirectionalStream (stream HelloRequest) returns (stream HelloResponse);
}

更新server.go实现双向流式处理:

func (s *server) SayHelloBidirectionalStream(stream pb.Greeter_SayHelloBidirectionalStreamServer) error {
	for {
		req, err := stream.Recv()
		if err == io.EOF {
			return nil
		}
		if err != nil {
			return err
		}
		if err := stream.Send(&pb.HelloResponse{Message: "Hello " + req.Name}); err != nil {
			return err
		}
	}
}

更新client.go处理双向流式通信:

stream, err := c.SayHelloBidirectionalStream(ctx)
if err != nil {
	log.Fatalf("could not greet: %v", err)
}
waitc := make(chan struct{})
go func() {
	for {
		msg, err := stream.Recv()
		if err == io.EOF {
			close(waitc)
			return
		}
		if err != nil {
			log.Fatalf("could not receive: %v", err)
		}
		log.Printf("Greeting: %s", msg.Message)
	}
}()
for _, name := range []string{"Alice", "Bob", "Charlie"} {
	if err := stream.Send(&pb.HelloRequest{Name: name}); err != nil {
		log.Fatalf("could not send: %v", err)
	}
}
stream.CloseSend()
<-waitc

5. 总结

本文介绍了如何在Golang中使用gRPC。我们首先了解了gRPC的基本概念,然后通过一个简单的例子演示了如何定义服务、生成代码、实现服务端和客户端。最后,我们探讨了gRPC的四种服务方法,包括Unary RPC、Server Streaming RPC、Client Streaming RPC和Bidirectional Streaming RPC。

gRPC是一个功能强大、性能优越的RPC框架,适用于构建高性能、跨语言的分布式系统。通过本文的学习,你应该能够在Golang中使用gRPC构建自己的服务。

推荐阅读:
  1. golang中函数怎么用
  2. golang中无法安装grpc的原因和解决方法

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

golang grpc

上一篇:WCF是什么

下一篇:golang中DES怎么用

相关阅读

您好,登录后才能下订单哦!

密码登录
登录注册
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》