一: 流模式总共有4种
1:标准模式,之前写的都是标准模式,一次请求一次返回
2:服务器流模式,客户端请求一次,服务器持续返回
3:客户端流模式,客户端持续请求,使用场景,物联网,温度监控(逻辑类似服务器流模式,不过多介绍,代码在双向流模式里)
4:双向流模式,客户端和服务器端持续发送数据,实用场景聊天机器人
实用场景:股票,一次请求会一直返回股票的实时数据
二:具体代码
proto文件
syntax = "proto3";
option go_package=".;proto";
service Greeter {
/*
服务器流模式,
在返回参数那里加stream
*/
rpc GetStream(StreamReqData) returns (stream StreamResData);
/*
客户端流模式,
在请求参数那里加stream
*/
rpc PutStream(stream StreamReqData) returns (StreamResData);
/*
双向流模式,
在请求参数和返回参数都加stream
*/
rpc AllStream(stream StreamReqData) returns (stream StreamResData);
}
message StreamReqData {
string data = 1;
}
message StreamResData {
string data = 1;
}
server
package main
import (
"google.golang.org/grpc"
"awesomePro/stream_grpc/proto"
"fmt"
"net"
"time"
)
const PORT = ":50051"
type server struct {
}
// 这里的参数是根据protobuf生成的go文件里面的代码传入
func (s *server)GetStream(req *proto.StreamReqData, res proto.Greeter_GetStreamServer)error{
i := 0
for{
i ++
_ = res.Send(&proto.StreamResData{
Data: fmt.Sprintf("%v", time.Now().Unix()),
})
time.Sleep(time.Second)
if i>10 {
break
}
}
return nil
}
func (s *server)PutStream(cliStr proto.Greeter_PutStreamServer)error{
return nil
}
func (s *server)AllStream(allStr proto.Greeter_AllStreamServer)error{
return nil
}
func main(){
lis, err := net.Listen("tcp", PORT)
if err != nil {
panic(err)
}
s := grpc.NewServer()
proto.RegisterGreeterServer(s, &server{})
err = s.Serve(lis)
if err != nil{
panic(err)
}
}
client
package main
import(
"awesomePro/stream_grpc/proto"
"context"
"fmt"
"google.golang.org/grpc"
)
func main(){
conn, err := grpc.Dial("localhost:50051", grpc.WithInsecure())
if err != nil{
panic(err)
}
defer conn.Close()
c := proto.NewGreeterClient(conn)
//GetStream接受的参数不是根据我们自己写的server传的,
//也是根据为我们生成的go文件传的。
res, err := c.GetStream(context.Background(), &proto.StreamReqData{Data:"book"})
for{
a, err :=res.Recv()
if err != nil{
panic(err)
}
fmt.Println(a)
}
}