更新时间:

#grpc stream 单向stream 双向stream

#前言

gRPC Streaming 是基于 HTTP/2 的 本章节将介绍 gRPC 的流式,分为三种类型:

Server-side streaming RPC:服务器端流式 RPC Client-side streaming RPC:客户端流式 RPC Bidirectional streaming RPC:双向流式 RPC

#为什么不用 Simple RPC

流式为什么要存在呢,是 Simple RPC 有什么问题吗?通过模拟业务场景,可得知在使用 Simple RPC 时,有如下问题:

数据包过大造成的瞬时压力 接收数据包时,需要所有数据包都接受成功且正确后,才能够回调响应,进行业务处理(无法客户端边发送,服务端边处理)

#为什么用 Streaming RPC

大规模数据包 实时场景 模拟场景 每天早上 6 点,都有一批百万级别的数据集要同从 A 同步到 B,在同步的时候,会做一系列操作(归档、数据分析、画像、日志等)。这一次性涉及的数据量确实大

在同步完成后,也有人马上会去查阅数据,为了新的一天筹备。也符合实时性。

两者相较下,这个场景下更适合使用 Streaming RPC

syntax = "proto3";

package proto;

service StreamService {
    rpc List(StreamRequest) returns (stream StreamResponse) {};

    rpc Record(stream StreamRequest) returns (StreamResponse) {};

    rpc Route(stream StreamRequest) returns (stream StreamResponse) {};
}


message StreamPoint {
  string name = 1;
  int32 value = 2;
}

message StreamRequest {
  StreamPoint pt = 1;
}

message StreamResponse {
  StreamPoint pt = 1;
}

注意关键字 stream,声明其为一个流方法。这里共涉及三个方法,对应关系为

List:服务器端流式 RPC Record:客户端流式 RPC Route:双向流式 RPC


关键函数 :
server stream : 

server: stream.Send(&pb.StreamResponse client: for { resp, err := stream.Recv() if err == io.EOF { break } if err != nil { return err }

	log.Printf("resp: pj.name: %s, pt.value: %d", resp.Pt.Name, resp.Pt.Value)
}
### client stream:
![ ](https://cf.maocaoying.com/images/2023/03/10/9eb52bc356148348a5a48d8659a5179c.png)

server: func (s *StreamService) Record(stream pb.StreamService_RecordServer) error { for { r, err := stream.Recv() if err == io.EOF { return stream.SendAndClose(&pb.StreamResponse{Pt: &pb.StreamPoint{Name: "gRPC Stream Server: Record", Value: 1}}) } if err != nil { return err }

	log.Printf("stream.Recv pt.name: %s, pt.value: %d", r.Pt.Name, r.Pt.Value)
}

return nil

}

client:

stream, err := client.Record(context.Background()) if err != nil { return err }

for n := 0; n < 6; n++ {
	err := stream.Send(r)
	if err != nil {
		return err
	}
}

resp, err := stream.CloseAndRecv()
if err != nil {
	return err
}

双向流式 RPC: 参见下边原文

流stream 的grpc 例子 :https://eddycjy.com/posts/go/grpc/2018-09-24-stream-client-server/


简单 grpc  https://eddycjy.com/posts/go/grpc/2018-09-23-client-and-server/