grpc的流模式例子
grpc的流模式例子
工程结构:
stream_grpc_test
├─client
│ client.go
│
├─proto
│ stream.pb.go
│ stream.proto
│
└─server
server.go
proto文件:
syntax = "proto3";
option go_package = "./;proto";
service Greeter{
rpc GetStream(StreamReqData) returns (stream StreamResData);//服务端流模式
rpc PutStream(stream StreamReqData) returns (StreamResData);//客户端端流模式
rpc AllStream(stream StreamReqData) returns (stream StreamResData);//双向流模式
}
message StreamReqData {
string data = 1;
}
message StreamResData {
string data = 1;
}
server:
package main
import (
"fmt"
"google.golang.org/grpc"
"grpctest/stream_grpc_test/proto"
"net"
"sync"
"time"
)
type myserver struct {
}
func (s *myserver) GetStream(data *proto.StreamReqData, server proto.Greeter_GetStreamServer) error {
for i := 0; i < 10; i++ {
err := server.Send(&proto.StreamResData{
Data: fmt.Sprintf("%v", time.Now().Unix()),
})
if err != nil {
return err
}
time.Sleep(time.Second)
}
return nil
}
func (s *myserver) PutStream(server proto.Greeter_PutStreamServer) error {
for {
if a, err := server.Recv(); err != nil{
fmt.Println(err)
break
} else {
fmt.Println(a.Data)
}
}
return nil
}
func (s *myserver) AllStream(server proto.Greeter_AllStreamServer) error {
wg := sync.WaitGroup{}
wg.Add(2)
go func() {
defer wg.Done()
for {
recv, err := server.Recv()
if err != nil {
return
}
fmt.Println("recv", recv.Data)
}
}()
go func() {
defer wg.Done()
for {
err := server.Send(&proto.StreamResData{Data: fmt.Sprintf("heiheihei")})
if err != nil {
return
}
time.Sleep(time.Second)
}
}()
wg.Wait()
return nil
}
func main() {
lis, err := net.Listen("tcp", ":18866")
if err != nil {
panic(err)
}
s := grpc.NewServer()
proto.RegisterGreeterServer(s, &myserver{})
err = s.Serve(lis)
if err != nil {
panic(err)
}
}
client:
package main
import (
"context"
"fmt"
"google.golang.org/grpc"
"grpctest/stream_grpc_test/proto"
"sync"
"time"
)
func main() {
dial, err1 := grpc.Dial("localhost:18866", grpc.WithInsecure())
if err1 != nil {
return
}
defer func(dial *grpc.ClientConn) {
err := dial.Close()
if err != nil {
panic(err)
}
}(dial)
client := proto.NewGreeterClient(dial)
//服务端流模式
stream, _ := client.GetStream(context.Background(), &proto.StreamReqData{
Data: "啦啦啦",
})
for {
recv, err := stream.Recv()
if err != nil {
fmt.Println("err:", err)
break
}
fmt.Println(recv)
}
//客户端流模式
putStream, err := client.PutStream(context.Background())
if err != nil {
return
}
for i := 0; i < 10; i++ {
putStream.Send(&proto.StreamReqData{Data: fmt.Sprintf("xixixi %d", i)})
time.Sleep(time.Second)
}
//双向流模式
allStream, err := client.AllStream(context.Background())
if err != nil {
return
}
wg := sync.WaitGroup{}
wg.Add(2)
go func() {
defer wg.Done()
for {
recv, err := allStream.Recv()
if err != nil {
return
}
fmt.Println("recv", recv.Data)
}
}()
go func() {
defer wg.Done()
for {
err := allStream.Send(&proto.StreamReqData{Data: fmt.Sprintf("hahaha")})
if err != nil {
return
}
time.Sleep(time.Second)
}
}()
wg.Wait()
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 零经验选手,Compose 一天开发一款小游戏!
· 通过 API 将Deepseek响应流式内容输出到前端
· AI Agent开发,如何调用三方的API Function,是通过提示词来发起调用的吗