grpc流模式

proto文件

syntax="proto3";
package services;

//用户模型
message UserInfo{
    
    
    int32 user_id=1;
    int32 user_score=2;
}

message UserScoreRequest{
    
    
    repeated UserInfo users=1;
}
message UserScoreResponse{
    
    
    repeated UserInfo users=1;
}
service UserService{
    
    
	//服务流模式
    rpc GetUserScoreByServerStream(UserScoreRequest) returns (stream UserScoreResponse);
    //客户流模式
    rpc GetUserScoreByClientStream(stream UserScoreRequest) returns (UserScoreResponse);
    //双向流模式
    rpc GetUserScoreByTWS(stream UserScoreRequest) returns (stream UserScoreResponse);
}

编译命令

protoc --go_out=plugins=grpc:../services Users.proto

一. 服务流模式。
在这里插入图片描述

  1. 实现方法
//服务端流模式
func(*UserService) GetUserScoreByServerStream(in *UserScoreRequest,stream UserService_GetUserScoreByServerStreamServer) error{
    
    
	var score int32=101		//模拟分数
	users:=make([]*UserInfo,0)		//用户切片
	//遍历传过来的用户切片
	for index,user:=range in.Users{
    
    
		user.UserScore=score		//新增模拟分数属性
		score++
		users=append(users,user)		//加到用户切片里面
		//每两组发送一次
		if (index+1) %2==0 && index>0{
    
    
			err:=stream.Send(&UserScoreResponse{
    
    Users:users})
			if err!=nil{
    
    
				return nil
			}
			users=(users)[0:0]	//清空用户切片
		}
	}
	return nil
}
  1. 客户端
//服务端流模式
func main(){
    
    
	conn,err:=grpc.Dial(":8081",grpc.WithTransportCredentials(helper.GetClientCreds()))
	if err!=nil{
    
    
		log.Fatal(err)
	}
	defer conn.Close()
	ctx:=context.Background()
	userClient:=services.NewUserServiceClient(conn)
	var i int32
	req:=services.UserScoreRequest{
    
    }
	req.Users=make([]*services.UserInfo,0)
	for i=1;i<=10;i++{
    
      //加了5条用户信息
		req.Users=append(req.Users,&services.UserInfo{
    
    UserId:i})
	}

	stream,err:=userClient.GetUserScoreByServerStream(ctx,&req)
	if err!=nil{
    
    
		log.Fatal(err)
	}
	for{
    
    
		//接收
		res,err:=stream.Recv()
		//接收完了
		if err==io.EOF{
    
    
			break
		}
		if err!=nil{
    
    
			log.Fatal(err)
		}
		fmt.Println(res.Users)
	}
}
  1. 结果
[user_id:1 user_score:101 user_id:2 user_score:102]
[user_id:3 user_score:103 user_id:4 user_score:104]
[user_id:5 user_score:105 user_id:6 user_score:106]
[user_id:7 user_score:107 user_id:8 user_score:108]
[user_id:9 user_score:109 user_id:10 user_score:110]

一. 服务流模式。
在这里插入图片描述

  1. 实现方法
//客户端流模式
func(*UserService) 	GetUserScoreByClientStream(stream UserService_GetUserScoreByClientStreamServer) error {
    
    
	var score int32 = 101
	users := make([]*UserInfo, 0)
	for {
    
    
		//接收
		req, err := stream.Recv()
		//接收完了返回结果并关闭
		if err == io.EOF {
    
    
			return stream.SendAndClose(&UserScoreResponse{
    
    Users: users})
		}
		if err != nil {
    
    
			return err
		}
		//接收user append到切片
		for _, user := range req.Users {
    
    
			user.UserScore = score
			score++
			users = append(users, user)
		}
	}
}
  1. 客户端
func main(){
    
    
	conn,err:=grpc.Dial(":8081",grpc.WithTransportCredentials(helper.GetClientCreds()))
	if err!=nil{
    
    
		log.Fatal(err)
	}
	defer conn.Close()

	ctx:=context.Background()
	userClient:=services.NewUserServiceClient(conn)
	var i int32
	if err!=nil{
    
    
		log.Fatal(err)
	}
	stream,err:=userClient.GetUserScoreByClientStream(ctx)
	if err!=nil{
    
    
		log.Fatal(err)
	}

	for j:=1;j<=3;j++{
    
    
		req:=services.UserScoreRequest{
    
    }
		req.Users=make([]*services.UserInfo,0)
		for i=1;i<=5;i++{
    
      //加了5条用户信息  假设是一个耗时的过程
			req.Users=append(req.Users,&services.UserInfo{
    
    UserId:i})
		}
		err:=stream.Send(&req)
		if err!=nil{
    
    
			log.Println(err)
		}
	}
	res,_:=stream.CloseAndRecv()
	fmt.Println(res.Users)
}
  1. 结果
[user_id:1 user_score:101 user_id:2 user_score:102 user_id:3 user_score:103 user_id:4 user_score:104 user_id:5 user_score:105 user_id:1 use
r_score:106 user_id:2 user_score:107 user_id:3 user_score:108 user_id:4 user_score:109 user_id:5 user_score:110 user_id:1 user_score:111 us
er_id:2 user_score:112 user_id:3 user_score:113 user_id:4 user_score:114 user_id:5 user_score:115]

三. 双向流模式
在这里插入图片描述

  1. 实现方法
func(*UserService) GetUserScoreByTWS(stream UserService_GetUserScoreByTWSServer) error  {
    
    
	var score int32=101
	users:=make([]*UserInfo,0)
	for{
    
    
		//接收
		req,err:=stream.Recv()
		if err==io.EOF{
    
     //接收完了
			return nil
		}
		if err!=nil{
    
    
			return err
		}
		//遍历传过来的用户切片
		for _,user:=range req.Users{
    
    
			user.UserScore=score  //这里好比是服务端做的业务处理
			score++
			users=append(users,user)
		}
		//发送
		err=stream.Send(&UserScoreResponse{
    
    Users:users})
		if err!=nil{
    
    
			log.Println(err)
		}
		//清空切片
		users=(users)[0:0]
	}
}
  1. 客户端
//双向流模式
func main(){
    
    
	//creds, err := credentials.NewClientTLSFromFile("keys/server.crt", "localhost")
	//if err != nil {
    
    
	//	log.Fatal(err)
	//}
	//创建连接
	conn,err:=grpc.Dial(":8081",grpc.WithTransportCredentials(helper.GetClientCreds()))
	if err!=nil{
    
    
		log.Fatal(err)
	}
	defer conn.Close()

	ctx:=context.Background()
	//客户端
	userClient:=services.NewUserServiceClient(conn)
	var i int32
	if err!=nil{
    
    
		log.Fatal(err)
	}
	//调用方法
	stream,err:=userClient.GetUserScoreByTWS(ctx)
	if err!=nil{
    
    
		log.Fatal(err)
	}

	var uid int32=1
	//分段执行三次
	for j:=1;j<=3;j++{
    
    
		//请求模型
		req:=services.UserScoreRequest{
    
    }
		req.Users=make([]*services.UserInfo,0)
		for i=1;i<=5;i++{
    
      //加5条用户信息  假设是一个耗时的过程
			req.Users=append(req.Users,&services.UserInfo{
    
    UserId:uid})
			uid++
		}
		//发送
		err:=stream.Send(&req)
		if err!=nil{
    
    
			log.Println(err)
		}
		//接收
		res,err:=stream.Recv()
		if err==io.EOF{
    
    
			break
		}
		if err!=nil{
    
    
			log.Println(err)
		}
		//打印
		fmt.Println(res.Users)
	}
	//res,_:=stream.CloseAndRecv()
	//fmt.Println(res.Users)
}
  1. 结果
[user_id:1 user_score:101 user_id:2 user_score:102 user_id:3 user_score:103 user_id:4 user_score:104 user_id:5 user_score:105 user_id:1 use
r_score:106 user_id:2 user_score:107 user_id:3 user_score:108 user_id:4 user_score:109 user_id:5 user_score:110 user_id:1 user_score:111 us
er_id:2 user_score:112 user_id:3 user_score:113 user_id:4 user_score:114 user_id:5 user_score:115]

服务端git地址: https://gitee.com/php_is_no1/gorpc.jtthink.com.git
客户端git地址:https://gitee.com/php_is_no1/gweb.jtthink.com.git

猜你喜欢

转载自blog.csdn.net/qq_36453564/article/details/108360827