go的grpc的三种流模式通信

go的grpc的三种流模式通信

    • 1、grpc通信模式简介
    • 2、stream.proto文件
    • 3、服务端代码 server.go
    • 4、客户端代码client.go
    • 5、测试说明

1、grpc通信模式简介

grpc的数据传输可以分为4种模式:
简单模式 (一元调用)
服务端流模式 (服务端返回实时股票数据给前台)
客户端流模式 (物联网硬件设备向后端发送数据)
双向流模式 (聊天场景)

2、stream.proto文件

syntax = "proto3";option go_package = "./;proto";// grpc的数据传输可以分为4种模式:
// 简单模式(一元调用)、服务端流模式(服务端返回实时股票数据给前台)、客户端流模式(物联网硬件设备向后端发送数据)、双向流模式(聊天场景)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;
}

生成客户端代理stub程序、服务端代理stub程序、接口相关代码的命令:
protoc --go_out=. --go-grpc_out=. stream.proto

3、服务端代码 server.go

package mainimport ("Go_Bible/stream_grpc_test/proto""fmt""google.golang.org/grpc""net""sync""time"
)// 端口
const PORT = ":8088"// 自定义服务结构体
type MyServer struct {proto.UnimplementedGreeterServer
}// 实现服务端流模式方法
func (s *MyServer) GetStream(req *proto.StreamReqData, srvStr proto.Greeter_GetStreamServer) error {i := 0for {i++// 向客户端发送响应结构体_ = srvStr.SendMsg(&proto.StreamResData{Data:fmt.Sprintf("%v", time.Now().Unix()),})time.Sleep(time.Second)// 每隔一秒发送1次,总共发送10次if i >= 10 {break}}return nil
}// 实现客户端流模式方法
func (s *MyServer) PutStream(cliStr proto.Greeter_PutStreamServer) error {for {if data, err := cliStr.Recv(); err != nil {fmt.Println("接受客户端的流数据失败:" + err.Error())break}else {fmt.Println("接受到客户端的流数据成功:" + data.Data)}}return nil
}// 实现双向流模式方法
func (s *MyServer) AllStream(allStr proto.Greeter_AllStreamServer) error {wg := sync.WaitGroup{}wg.Add(2)go func() {defer wg.Done()i := 0for {i++// 向客户端发送响应结构体_ = allStr.SendMsg(&proto.StreamResData{Data: fmt.Sprintf("我是服务器 %d", i)})time.Sleep(time.Second)if i >= 10 {break}}}()go func() {defer wg.Done()for {data, _ := allStr.Recv()fmt.Println("服务端接受到客户端的流数据成功:" + data.Data)}}()// 等待相关协程开启调用完成wg.Wait()return nil
}func main() {// 1、监听端口listener, err := net.Listen("tcp", PORT)if err != nil {panic("监听端口失败:" + err.Error())}// 2、创建服务server := grpc.NewServer()// 3、注册服务proto.RegisterGreeterServer(server, &MyServer{})// 4、启动服务err = server.Serve(listener)if err != nil {panic("启动服务失败:" + err.Error())}
}

4、客户端代码client.go

package mainimport ("Go_Bible/stream_grpc_test/proto""context""fmt""google.golang.org/grpc""strconv""sync""time"
)// testGetStream 测试服务端流模式
func testGetStream(client proto.GreeterClient){res, err := client.GetStream(context.Background(), &proto.StreamReqData{Data: "我是客户端"})if err != nil {panic("服务端流模式,从服务端获取数据失败:" + err.Error())}for {data, err := res.Recv()if err != nil {fmt.Println("从服务端获取数据失败:" + err.Error())break}fmt.Println("从服务端获取到数据成功:" + data.Data)}
}// testPutStream 测试客户端流模式
func testPutStream(client proto.GreeterClient){putStrClient, err := client.PutStream(context.Background())if err != nil {panic("客户端流模式,向服务端发送数据失败:" + err.Error())}i := 0for {i++fmt.Println(i)if err = putStrClient.Send(&proto.StreamReqData{Data: strconv.Itoa(i)}); err != nil {fmt.Println("喜爱那个服务端发送数据失败:" + err.Error())break}time.Sleep(time.Second)if i >= 10 {break}}
}// testAllStream 测试双向流模式
func testAllStream(client proto.GreeterClient){allStrClient, err := client.AllStream(context.Background())if err != nil {panic("双向流模式获取失败:" + err.Error())}wg := sync.WaitGroup{}wg.Add(2)// 向服务端发送数据 因为服务端会从客户端源源不断获取数据,因此服务端也不会自动关闭go func() {defer wg.Done()i := 0for {i++err = allStrClient.Send(&proto.StreamReqData{Data: fmt.Sprintf("双向流模式发送的数据:%d", i)})if err != nil {fmt.Println("双向流模式向服务端发送数据失败:" + err.Error())break}if i >= 10 {break}}}()// 从服务端接受数据,因为双向流模式时,客户端需要从服务端源源不断接受数据,因此不会关闭go func() {defer wg.Done()for {data, err := allStrClient.Recv()if err != nil {fmt.Println("双向流模式从服务端接受数据失败:" + err.Error())break}fmt.Println("双向流模式收到服务端消息:" + data.Data)}}()wg.Wait()
}func main() {//	1、拨号conn, err := grpc.Dial("localhost:8088", grpc.WithInsecure())if err != nil {panic("连接失败:" + err.Error())}// 关闭连接defer conn.Close()//2、创建客户端client := proto.NewGreeterClient(conn)/*3、测试服务端流模式*///testGetStream(client)/*4、测试客户端流模式*///testPutStream(client)/*5、测试双向流模式*/testAllStream(client)
}

5、测试说明

先启动服务端server.go
再启动客户端client.go,调用对应函数进行测试

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/5975.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

kubernetes中使用ELK进行日志收集

目录 一、需要收集哪些日志 1、kubernetes集群的系统组件日志 2、应用日志 二、日志收集方案ELK 1、收集日志:Logstash 2、存储日志:Elasticsearch 3、展示日志:Kibana 三、安装elk 1、下载安装包 2、创建用户并切换到新用户 3、上…

npm许可证检查

node开发做项目,很少有人去纯手工打造,大多是采用一些开源框架,还会使用前人做好的轮子,所以咱们的项目文件里,除了自己编写的js文件,还会带有一些拿来主义的npm模块,从其他开源发布网站上下载的…

2024-05-02 商业分析-杭州小万科技-商业模式分析

摘要: 对杭州小万科技的商业模式进行分析,以对其做出客观的评估。 杭州小万科技的资料: 杭州小万科技有限公司 - 企知道 (qizhidao.com) 杭州小万科技有限公司网站备案查询 - 天眼查 (tianyancha.com) 杭州小万科技有限公司 - 爱企查 (baidu.com) ​ 2023年年报:

SMB 协议详解之-TreeID原理和SMB数据包分析技巧

在前面分析SMB协议数据包的过程中,这里,可以看到在SMB协议中存在很多的ID,即Unique Identifiers。那么这些ID表示什么含义?在实际分析数据包的过程中如何根据这些ID进行过滤分析?本文将介绍SMB/SMB2中的tree id ,并介绍如何通过tree id 快速的分析SMB数据包中各种命令交互…

Django响应‘表单请求’过程

(1)用户通过自己的浏览器(客户端)第一次向服务器发出含有表单页面的请求,Django会创建一个未绑定数据的表单实例(例如form LoginForm(), form实例就是未绑定实例),即空表单&#xf…

现代JavaScript:对ES6+的深入讲解,新型的JS特性以及怎样在项目中使用它们

现代JavaScript,也就是ES6(ECMAScript 6)和更高版本,引入了很多新的语言特性来增强JavaScript的编程能力。以下为一些关键的新特性及其在项目中的使用: 1、let 和 const 关键字: 在ES6之前,我们…

使用jdbc方式操作ClickHouse

1、创建测试表,和插入测试数据 create table t_order01(id UInt32,sku_id String,total_amount Decimal(16,2),create_time Datetime ) engine MergeTreepartition by toYYYYMMDD(create_time)primary key (id)order by (id,sku_id);insert into t_order01 values …

MR混合现实情景实训教学系统在商务接待课堂上的应用

随着科技的不断发展,MR混合现实情景实训教学系统已经逐渐应用于商务接待课堂。这种新型的实训教学系统将虚拟现实技术与现实环境相结合,为商务接待课堂带来了全新的教学方式和体验。 首先,MR混合现实情景实训教学系统能够为学生提供真实的商务…

Agent AI智能体:如何借助机器学习引领科技新潮流

文章目录 📑前言一、Agent AI智能体的基本概念二、Agent AI智能体的技术进步2.1 机器学习技术2.2 自适应技术2.3 分布式计算与云计算 三、Agent AI智能体的知识积累3.1 知识图谱3.2 迁移学习 四、Agent AI智能体的挑战与机遇4.1 挑战4.2 机遇 小结 📑前言…

App异常汇总与对策

UI交互异常 空显示/白屏 一般是因为数据为空或获取失败。要请产品定义加载中、加载失败、数据为空的UI。显示不完整、错位 开发时考虑不同屏幕大小、窗体大小、内容量的兼容,做好对齐和层级的设置。内容量会引起折行、显示不全等问题。如果有改变字体大小或多语言设…

Java基础(10)反射

Java反射是Java语言中的一个功能强大且复杂的机制,它允许程序在运行时访问、检查和修改它本身的结构(类、接口、字段、方法等)。反射机制主要在java.lang.reflect包中定义。 反射的核心组件 Class类:它的实例表示正在运行的Java…

【网站项目】高校推免报名

🙊作者简介:拥有多年开发工作经验,分享技术代码帮助学生学习,独立完成自己的项目或者毕业设计。 代码可以私聊博主获取。🌹赠送计算机毕业设计600个选题excel文件,帮助大学选题。赠送开题报告模板&#xff…

K8s: Kubernetes扩展之自定义资源

自定义资源 自定义资源是 K8s 的扩展,有时候需要对K8s进行一个扩展在默认的K8s集群里面提供的资源对象是一个有限的集合比如常用的pod, deployment, service,这些都是K8s原生的资源之所以它资源,是因为它能够对外提供API接口变成一个resourc…

Java-异常处理-定义三角形类Triangle和异常三角形IllegalTriangleException类 (1/2)

任意一个三角形,其任意两边之和大于第三边。当三角形的三条边不满足前述条件时,就表示发生了异常,将这种异常情况定义为IllegalTriangleException类。 自定义异常类IllegalTriangleException: 当三角形的三条边不满足条件&#x…

[随记]Mac安装Docker及运行开源Penpot

下载Docker Desktop for Mac:https://www.docker.com/products/docker-desktop/ 安装Docker Desktop for Mac,安装完成后,启动Docker,然后在终端输入: docker version 在Mac电脑的Desktop,随便创建一个文…

零代码编程:用通义千问免费批量翻译英文文档

首先,在阿里云的dashScope灵积模型服务中,申请一个API-key,有挺多免费token的。 然后,在通义千问中输入提示词: 你是一个Python编程专家,现在要完成一个编写基于qwen-turbo模型API和dashscope库的程序脚本…

UML图(总结)

一、静态建模 1、类图: 展现了一组对象、接口、协作和它们之间的关系。 2、对象图 展现了某一时刻一组对象以及它们之间的关系。 3、用例图 展现了用例、参与者(Action)以及它们之间的关系。 二、动态建模 1、序列图(顺序图,时序图) 描述了以…

Android Handler用法

Android Handler用法 为什么要设计Handler机制?Handler的用法1、创建Handler2、Handler通信2.1 sendMessage 方式2.2 post 方式 Handler常用方法1、延时执行2、周期执行 HandlerThread用法主线程-创建Handler子线程-创建Handler FAQMessage是如何创建主线程中Looper…

云端芳华、运维之美

今天,在我们享受互联网服务带来的便利与高效的同时,有一群人默默地在幕后为我们提供支持,他们就是云端运维人员。 值此五一国际劳动节来临之际,我们要真诚感谢他们辛勤的劳动和奉献!

vue2集成ElementUI编写登录页面

目录 1. 整理目录文件: a. app.vue文件如下: b. Login.vue文件如下: c. router/index.js文件如下: d. 删除components中的文件: e. 最终项目目录整理如下: 2. 集成ElementUI编写登录页面 a. 安装ElementUI: b. 在main.js