流模式定义
流模式需要stream标识,由于实现服务端流效果,所以返回结果使用stream标识
syntax = "proto3";
option go_package = "./;streampb";
message StreamReqData{
string data = 1;
}
message StreamResData{
string data = 1;
}
service Greeter {
rpc GetStream(StreamReqData) returns (stream StreamResData);
}
生成代码
protoc -I . stream.proto --go_out=plugins=grpc:.
服务端实现
流程和一元rpc差不多,唯一的区别是入参多了一个参数(Greeter_GetStreamServer),该参数有send方法发送数据
Greeter_GetStreamServer 名字是proto中 rpc中声明的服务名 + “_” + rpc方法名 + server
package main
import (
streampb "Study/Four/pro"
"fmt"
"google.golang.org/grpc"
"net"
"time"
)
type service struct {
}
func (s *service) GetStream(req *streampb.StreamReqData, res streampb.Greeter_GetStreamServer) error {
count := 0
for {
time.Sleep(time.Second)
count++
res.Send(&streampb.StreamResData{
Data: fmt.Sprintf("data:%s,time:%d", req.Data, count),
})
}
}
func main() {
server := grpc.NewServer()
streampb.RegisterGreeterServer(server, &service{})
listen, _ := net.Listen("tcp", ":8088")
server.Serve(listen)
}
客户端实现
使用也和一元rpc差不多,唯一的区别是返回的类型,流模式下返回的res提供Recv获取数据
package main
import (
streampb "Study/Four/pro"
"context"
"fmt"
"google.golang.org/grpc"
)
func main() {
dial, _ := grpc.Dial(":8088", grpc.WithInsecure())
client := streampb.NewGreeterClient(dial)
stream, _ := client.GetStream(context.Background(), &streampb.StreamReqData{
Data: "let's go",
})
for {
if res, err := stream.Recv(); err == nil {
fmt.Println(res)
}
}
}
运行结果