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版


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

相关内容

热门资讯

一分钟内幕!科乐吉林麻将系统发... 一分钟内幕!科乐吉林麻将系统发牌规律,福建大玩家确实真的是有挂,技巧教程(有挂ai代打);所有人都在...
一分钟揭秘!微扑克辅助软件(透... 一分钟揭秘!微扑克辅助软件(透视辅助)确实是有挂(2024已更新)(哔哩哔哩);1、用户打开应用后不...
五分钟发现!广东雀神麻雀怎么赢... 五分钟发现!广东雀神麻雀怎么赢,朋朋棋牌都是是真的有挂,高科技教程(有挂方法)1、广东雀神麻雀怎么赢...
每日必看!人皇大厅吗(透明挂)... 每日必看!人皇大厅吗(透明挂)好像存在有挂(2026已更新)(哔哩哔哩);人皇大厅吗辅助器中分为三种...
重大科普!新华棋牌有挂吗(透视... 重大科普!新华棋牌有挂吗(透视)一直是有挂(2021已更新)(哔哩哔哩)1、完成新华棋牌有挂吗的残局...
二分钟内幕!微信小程序途游辅助... 二分钟内幕!微信小程序途游辅助器,掌中乐游戏中心其实存在有挂,微扑克教程(有挂规律)二分钟内幕!微信...
科技揭秘!jj斗地主系统控牌吗... 科技揭秘!jj斗地主系统控牌吗(透视)本来真的是有挂(2025已更新)(哔哩哔哩)1、科技揭秘!jj...
1分钟普及!哈灵麻将攻略小,微... 1分钟普及!哈灵麻将攻略小,微信小程序十三张好像存在有挂,规律教程(有挂技巧)哈灵麻将攻略小是一种具...
9分钟教程!科乐麻将有挂吗,传... 9分钟教程!科乐麻将有挂吗,传送屋高防版辅助(总是存在有挂)1、完成传送屋高防版辅助透视辅助安装,帮...
每日必看教程!兴动游戏辅助器下... 每日必看教程!兴动游戏辅助器下载(辅助)真是真的有挂(2025已更新)(哔哩哔哩)1、打开软件启动之...