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()
}
posted @   DarkH  阅读(72)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 零经验选手,Compose 一天开发一款小游戏!
· 通过 API 将Deepseek响应流式内容输出到前端
· AI Agent开发,如何调用三方的API Function,是通过提示词来发起调用的吗
点击右上角即可分享
微信分享提示