grpc学习golang版( 六、服务器流式传输 )
创始人
2025-01-18 06:33:03
0

系列文章目录
第一章grpc基本概念与安装
第二章grpc入门示例
第三章proto文件数据类型
第四章多服务示例
第五章多proto文件示例
第六章服务器流式传输
第七章客户端流式传输
第八章双向流示例


文章目录

  • 一、前言
  • 二、定义proto文件
  • 三、拷贝任意文件进项目
  • 四、编写server服务端
  • 五、编写client客户端
  • 六、测试
  • 六、示例代码


一、前言

前面我们一直在讲的是服务端、客户端一问一答,最普通且常用的RPC服务。接下来本文介绍的是服务器流式传输。主要应用场景就是客户端请求服务端,从服务端下载视频、文件、图片等等。

二、定义proto文件

新建stream.proto文件

// 指定proto版本 syntax = "proto3"; // 指定默认包名 package stream_proto; // 指定golang包名 option go_package = "/stream_proto";  //定义个流服务,叫什么名字无所谓 service ServiceStream {   //下载文件,关键字stream   rpc DownloadFile(Request)returns(stream FileResponse){} } //请求参数 message Request{   string name = 1; }  //文件回调参数 message FileResponse{   //字节数据类型,即文件内容、数据   bytes content =1; } 

go_grpc_study/example_4/grpc_proto目录下新建Terminal,执行生成文件,命令如下

protoc --go_out=. --go-grpc_out=. ./stream.proto 

目录结构变更后为

具体步骤如下:

  • 1)定义回调message结构体FileResponse,使用bytes数据类型
  • 2)定义ServiceStream服务
  • 2)在服务里面,定义rpc方法DownloadFile,使用关键词stream回调FileResponse结构体

三、拷贝任意文件进项目

任意文件,可以是视频、音频、图片、文档等等,不做限制。这里以一张png图片为例。
新建static目录,拷贝一张grpc.pngstatic目录
图片如下:

目录结构如下

四、编写server服务端

新建server目录,新建main.go文件
目录结构如下

编写server/main.go文件

package main  import ( 	"fmt" 	"go_grpc_study/example_4/grpc_proto/stream_proto" 	"google.golang.org/grpc" 	"io" 	"log" 	"net" 	"os" )  //服务端流式  // 新版本 gRPC 要求必须嵌入 UnimplementedGreeterServer 结构体 type ServiceStream struct { 	stream_proto.UnimplementedServiceStreamServer }  func (ServiceStream) DownloadFile(request *stream_proto.Request, stream stream_proto.ServiceStream_DownloadFileServer) error { 	fmt.Println("DownloadFile", request) 	//分片读的方式读取图片 	file, err := os.Open("../static/grpc.png") 	if err != nil { 		return err 	} 	defer file.Close() 	for { 		buf := make([]byte, 1024) 		_, err = file.Read(buf) 		//当读取完后跳出循环 		if err == io.EOF { 			break 		} 		//出现异常后跳出循环 		if err != nil { 			break 		} 		stream.Send(&stream_proto.FileResponse{ 			Content: buf, 		}) 	}  	return nil }  func main() { 	// 监听端口 	listen, err := net.Listen("tcp", ":8080") 	if err != nil { 		log.Fatal(err) 	} 	// 创建一个gRPC服务器实例。 	s := grpc.NewServer() 	// 将server结构体注册为gRPC服务。 	stream_proto.RegisterServiceStreamServer(s, &ServiceStream{}) 	fmt.Println("grpc server running :8080") 	// 开始处理客户端请求。 	err = s.Serve(listen) } 

具体步骤如下:

  • 1)定义1个结构体,结构体名称无所谓,必须包含stream_proto.UnimplementedServiceStreamServer 对象
  • 2)实现 .proto文件中定义的API即DownloadFile下载文件方法
  • 3)分片读的方式读取图片,并把图片数据响应给客户端,每次1024个字节数据
  • 4)将服务描述及其具体实现注册到 gRPC

五、编写client客户端

新建client目录,新建main.go文件
目录结构如下

编写clinet/main.go文件

package main  import ( 	"bufio" 	"context" 	"fmt" 	"go_grpc_study/example_4/grpc_proto/stream_proto" 	"google.golang.org/grpc" 	"google.golang.org/grpc/credentials/insecure" 	"io" 	"log" 	"os" )  func main() { 	addr := ":8080" 	// 使用 grpc.Dial 创建一个到指定地址的 gRPC 连接。 	// 此处使用不安全的证书来实现 SSL/TLS 连接 	conn, err := grpc.Dial(addr, grpc.WithTransportCredentials(insecure.NewCredentials())) 	if err != nil { 		log.Fatalf(fmt.Sprintf("grpc connect addr [%s] 连接失败 %s", addr, err)) 	} 	defer conn.Close()  	client := stream_proto.NewServiceStreamClient(conn) 	//发送消息给服务端 	stream, err := client.DownloadFile(context.Background(), &stream_proto.Request{ 		Name: "周八", 	}) 	//缓冲写的方式另存为新的图片 	//os.O_CREATE : 创建并打开一个新文件 	//os.O_TRUNC :打开一个文件并截断它的长度为零(必须有写权限) 	//os.O_WRONLY :以只写的方式打开 	file, err := os.OpenFile("../static/grpc_new.png", os.O_CREATE|os.O_TRUNC|os.O_WRONLY, 0666) 	if err != nil { 		log.Fatalln(err) 	} 	defer file.Close() 	writer := bufio.NewWriter(file)  	var index int 	for { 		index++ 		response, errRecv := stream.Recv() 		if errRecv == io.EOF { 			break 		} 		if errRecv != nil { 			fmt.Println(errRecv) 			break 		} 		fmt.Printf("第 %d 次,写入 %d 数据\n", index, len(response.Content)) 		writer.Write(response.Content) 	} 	writer.Flush() } 

具体步骤如下:

  • 1)首先使用 grpc.Dial()gRPC 服务器建立连接
  • 2)使用 stream_proto.NewServiceStreamClient(conn)初始化客户端
  • 3)通过客户端调用ServiceAPI方法client.DownloadFile,并得到stream对象
  • 4)通过stream对象的Recv()方法得到[]byte数据
  • 5)通过缓冲写的方式另存为新的图片grpc_new.png

六、测试

server目录下,启动服务端

go run main.go 

clinet目录下,启动客户端

go run main.go 

服务端运行结果

客户端运行结果。我这个图片是119808 字节,最后走了 117 次,写入1024 数据

客户端下载的图片保存结果

六、示例代码

go_grpc_study:grpc学习golang版


完成ヾ(◍°∇°◍)ノ゙

相关内容

热门资讯

开挂办法!闲乐互娱源码,猎鱼达... 开挂办法!闲乐互娱源码,猎鱼达人破解版无限弹头,详细教程(有挂教学)在进入闲乐互娱源码软件靠谱后,参...
解密指南!随意玩5元流量包,腾... 您好,腾达填大坑辅助器这款游戏可以开挂的,确实是有挂的,需要了解加去威信【485275054】很多玩...
总结课程!边锋游戏小程序辅助器... 总结课程!边锋游戏小程序辅助器免费,榆林打锅子辅助器,详细教程(有挂教程)1、很好的工具软件,可以解...
解迷手册!微乐小程序辅助器脚本... 解迷手册!微乐小程序辅助器脚本,蘑菇云辅助,详细教程(真的有挂)1、微乐小程序辅助器脚本辅助器安装包...
了解课程!腾威互娱破解辅助工具... 了解课程!腾威互娱破解辅助工具,中至余干破解器,详细教程(有挂详情)1、下载好腾威互娱破解辅助工具透...
了解攻略!随意玩怎么创建聚乐部... 了解攻略!随意玩怎么创建聚乐部,新卡农辅助软件,详细教程(有挂总结)1、玩家可以在随意玩怎么创建聚乐...
必备积累!斗棋联盟辅助,创思维... 必备积累!斗棋联盟辅助,创思维激k辅助器视频,详细教程(证实有挂)1、创思维激k辅助器视频辅助器安装...
关于阶段!川南九九辅助,新九游... 关于阶段!川南九九辅助,新九游辅助软件,详细教程(有挂辅助);1、这是跨平台的川南九九辅助轻量版有透...
开挂模板!丽水都莱辅助软件,掌... 开挂模板!丽水都莱辅助软件,掌中乐游戏中心破解版,详细教程(有挂猫腻)丽水都莱辅助软件辅助器是一种具...
辅助手册!山西扣点点辅助工具免... 辅助手册!山西扣点点辅助工具免费,随意玩俱乐部辅助,详细教程(有挂方式)1、全新机制【山西扣点点辅助...