gRPC开发: gRPC的四种通信模式

本文深入介绍了gRPC的四种通信模式:一元RPC、服务端流RPC、客户端流RPC和双向流RPC。通过示例展示了如何在Go语言中实现这些模式,包括服务定义、服务端和客户端的代码实现,以及通信流程的关键细节。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

引言


gRPC应用程序共有四种基础的通信模式,分别为:一元RPC,服务端流RPC,客户端流RPC以及双向流RPC
注:阅读本文,如果没有gRPC基础的同学可以看我之前关于如何简单构建gRPC客户端和服务端的文章:

gRPC开发:go语言构建简单的服务端和客户端

一元RPC模式


[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-2FYsWpgr-1645887063623)(https://s3-us-west-2.amazonaws.com/secure.notion-static.com/7dc1fb85-2adc-4b01-8f5b-4db0ba69ce49/Untitled.png)]

服务定义:

//ecommerce/order_management.pb.go

syntax="proto3";
//导入这个包,使用常用的数据类型,如StringValue
import "google/protobuf/wrappers.proto";
package ecommerce;

option go_package = "../ecommerce";
service OrderManagement{
   
  rpc getOrder(google.protobuf.StringValue) returns (Order);//检索订单的远程方法
}

message Order{
   
  string id = 1;
  repeated string items = 2;//repeated表示该字段可以在消息中重复出现任意次
  string description = 3;
  float price = 4;
  string destination = 5;
}

服务端实现

//main.go
package main

import (
	"context"
	wrapper "github.com/golang/protobuf/ptypes/wrappers"
	"google.golang.org/grpc"
	"google.golang.org/grpc/codes"
	"google.golang.org/grpc/status"
	"log"
	"net"
	pb "orderServiceUnaryGRPC/service/ecommerce"
)

// 服务定义
type server struct {
   
	orderMap map[string]*pb.Order
}

const (
	port = ":50051"
)

var orderMap = make(map[string]pb.Order)

// 初始化订单信息
func initSampleData() {
   
	orderMap["102"] = pb.Order{
   Id: "102", Items: []string{
   "Google Pixel 3A", "Mac Book Pro"}, Destination: "Mountain View, CA", Price: 1800.00}
	orderMap["103"] = pb.Order{
   Id: "103", Items: []string{
   "Apple Watch S4"}, Destination: "San Jose, CA", Price: 400.00}
	orderMap["104"] = pb.Order{
   Id: "104", Items: []string{
   "Google Home Mini", "Google Nest Hub"}, Destination: "Mountain View, CA", Price: 400.00}
	orderMap["105"] = pb.Order{
   Id: "105", Items: []string{
   "Amazon Echo"}, Destination: "San Jose, CA", Price: 30.00}
	orderMap["106"] = pb.Order{
   Id: "106", Items: []string{
   "Amazon Echo", "Apple iPhone XS"}, Destination: "Mountain View, CA", Price: 300.00}
}

// GetOrder 通过订单编号获取订单消息
func (s *server) GetOrder(ctx context.Context, orderId *wrapper.StringValue) (*pb.Order, error) {
   
	//服务实现
	ord, exists := orderMap[orderId.Value]
	if exists {
   
		return &ord, status.New(codes.OK, "").Err()
	}
	return nil, status.Errorf(codes.NotFound, "Order does not exist.:", orderId)
}

func main() {
   
	initSampleData()
	lis, err := net.Listen("tcp", port)
	if err != nil {
   
		log.Fatalf("failed to listen:%v", err)
	}
	log.Printf("Starting gRPC listener on port:%s", port)
	s := grpc.NewServer()
	pb.RegisterOrderManagementServer(s, &server{
   })
	// 在指定端口上开始监听传入的消息
	if err := s.Serve(lis); err != nil {
   
		log.Fatalf("failed to serve:%v", err)
	}
}

客户端实现

//main.go
package main

import (
	"context"
	wrapper "github.com/golang/protobuf/ptypes/wrappers"
	"google.golang.org/grpc"
	"google.golang.org/grpc/credentials/insecure"
	"log"
	pb "orderServiceUnaryGRPC/client/ecommerce"
	"time"
)

const (
	address = "localhost:50051"
)

func main() {
   
	conn, err := grpc.Dial(address, grpc.WithTransportCredentials(insecure.NewCredentials()))
	if err != nil {
   
		log.Fatalf("Did not connect:%v", err)
	}
	defer conn.Close()
	client := pb.NewOrderManagementClient(conn)
	ctx, cancel := context.WithTimeout(context.Background(), time.Second*5)
	defer cancel()

	// 获取订单
	ord, err := client.GetOrder(ctx, &wrapper.StringValue{
   Value: "105"})
	log.Printf("GetOrder Response ->:%v", ord)
}

服务器端流RPC模式


[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-CM1DEmYb-1645887063625)(https://s3-us-west-2.amazonaws.com/secure.notion-static.com/3fe97dcc-be8c-49f2-9027-804d83d1f23e/Untitled.png)]

在一元 RPC 模式中,gRPC 服务器端和 gRPC 客户端在通信时始终只有 一个请求和一个响应。在服务器端流 RPC 模式中,服务器端在接收到 客户端的请求消息后,会发回一个响应的序列。这种多个响应所组成的 序列也被称为“流”。在将所有的服务器端响应发送完毕之后,服务器端 会以 trailer 元数据的形式将其状态发送给客户端,从而标记流的结束。

服务定义

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值