Go Grpc的四种流

srteam 顾名思义 就是 一种 流,可以源源不断的 推送 数据,很适合 传输一些大数据,或者 服务端 和 客户端 长时间 数据交互,比如 客户端 可以向 服务端 订阅 一个数据,服务端 就 可以利用 stream ,源源不断地 推送数据。
1. grpc的四种数据流

1.简单模式

2.服务端数据流模式(Server-side streaming RPC)

3.客户端数据流模式(Client-side streaming RPC)

4.双向数据流模式(Bidirectional streaming RPC)

简单模式

  这种模式最为传统,即客户端发起一次请求,服务端响应一个数据,这和大家平时熟悉的RPC没有什么大的区别,上两篇中介绍此模式。

服务端数据流模式

  这种模式是客户端发起一次请求,服务端返回一段连续的数据流。典型的例子是客户端向服务端发送一个股票代码,服务端就把该股票的实时数据源源不断的返回给客户端、

客户端数据流模式

与服务端数据流模式相反,这次是客户端源源不断的向服务端发送数据流,而在发送结束后,由服务端返回一个响应。典型的例子是物联网终端向服务器报送数据。

双向数据流模式

顾名思义,这是客户端和服务端都可以向对方发送数据流,这个时候双方的数据可以同时互相发送,也就是可以实现实时交互。典型的例子是聊天机器人。

2编写stream.proto

 

 

 生成go的protobuf文件命令

 

 生成后的文件如下:

\

 

 

 

 3.编写服务端server.go

package main

import (
"OldPacketTest/stream_grpc/proto"
"fmt"
"google.golang.org/grpc"
"net"
"sync"
"time"
)

const PORT = ":50052"

type Server struct {
proto.UnimplementedGreeterServer
}

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 {
for {
if a, err := cliStr.Recv(); err != nil {
fmt.Println(err)
break
} else {
fmt.Println(a.Data)
}
}
return nil
}

func (s *Server) AllStream(allStr proto.Greeter_AllStreamServer) error {
wg := sync.WaitGroup{}
wg.Add(2)
go func() {
wg.Done()
for {
data, _ := allStr.Recv()
fmt.Println("收到客户端消息:" + data.Data)
}
}()
go func() {
defer wg.Done()
for {
_ = allStr.Send(&proto.StreamResData{Data: "我是服务器"})
time.Sleep(time.Second)
}
}()
wg.Wait()
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)
}
}
4.编写客户端文件
package main

import (
"OldPacketTest/stream_grpc/proto"
"context"
"fmt"
"google.golang.org/grpc"
"sync"
"time"
)

func main() {
conn, err := grpc.Dial("localhost:50052", grpc.WithInsecure())
if err != nil {
panic(err)
}
defer conn.Close()

//服务端流模式
c := proto.NewGreeterClient(conn)
res, _ := c.GetStream(context.Background(), &proto.StreamReqData{
Data: "你好呀",
})
for {
a, err := res.Recv()
if err != nil {
fmt.Println(err)
break
}
fmt.Println(a)
}
//客户端流模式
putS, _ := c.PutStream(context.Background())
i := 0
for {
i++
_ = putS.Send(&proto.StreamReqData{
Data: fmt.Sprintf("慕课网%d", i),
})
time.Sleep(time.Second)
if i > 10 {
break
}
}
//双向流模式
allStr, _ := c.AllStream(context.Background())
wg := sync.WaitGroup{}
wg.Add(2)
go func() {
wg.Done()
for {
data, _ := allStr.Recv()
fmt.Println("收到服务端消息:" + data.Data)
}
}()
go func() {
defer wg.Done()
for {
_ = allStr.Send(&proto.StreamReqData{Data: "我是客户端"})
time.Sleep(time.Second)
}
}()
wg.Wait()
}
5.运行服务端和客户端
客户端响应的消息

 


 服务端响应的消息

 

 

 
posted @ 2023-02-12 20:30  lisus2000  阅读(175)  评论(0编辑  收藏  举报