go的grpc的三种流模式通信

news/2024/5/17 17:31:31

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.mrgr.cn/p/82842585

相关文章

2024-05-01 通达信指标 获利比例

平均成本线:COST(50),COLORYELLOW,NODRAW;三十周成本:LWINNER(150,C)COLORYELLOW;获利比例:WINNER(C)*100,COLORGREEN; DRAWLINE(O,90,O,90,1),COLORWHITE;DRAWLINE(O,70,O,70,1),COLORWHITE;

量子城域网建设设备系列(二):量子密钥管系统(KMS)

在上文介绍光量子交换机的文章中我们提到,量子保密通信网络的通道切换是由量子密钥管理系统(Key Management System,KMS)给光量子交换机下发信道切换指令,实现整个网络中任意两对量子密钥分发终端的量子信道互联互通&a…

二.Django项目之电商购物商城 -- 校验用户输入密码是否合法

Django项目之电商购物商城 – 校验用户输入密码是否合法 需要开发文档和前端资料的可私聊 一. 创建用户逻辑操作 1. 创建用户app – users python manage.py startapp users2.注册app users.apps.UsersConfig,3. 创建视图 from django.shortcuts import render from djan…

GPT是什么?直观解释Transformer | 深度学习第5章 【3Blue1Brown 官方双语】

【官方双语】GPT是什么?直观解释Transformer | 深度学习第5章 0:00 - 预测,采样,重复:预训练/生成式/Transformer模型 3:03 - Transformer 的内部结构 6:36 - 本期总述 7:20 - 深度学习的大框架 12:27 - GPT的第一层:…

【GitHub】github学生认证,在vscode中使用copilot的教程

github学生认证并使用copilot教程 写在最前面一.注册github账号1.1、注册1.2、完善你的profile 二、Github 学生认证注意事项:不完善的说明 三、Copilot四、在 Visual Studio Code 中安装 GitHub Copilot 扩展4.1 安装 Copilot 插件4.2 配置 Copilot 插件&#xff0…

Nacos 安全零信任实践

作者:柳遵飞 Nacos 作为配置中心经常存储一些敏感信息,但是由于误用导致安全风险,最常见的主要是以下两个问题: 1)Nacos 暴露公网可以吗?不可以,因为 Nacos 定位是注册配置中心,是…

中间件之异步通讯组件RabbitMQ入门

一、概述 微服务一旦拆分,必然涉及到服务之间的相互调用,目前我们服务之间调用采用的都是基于OpenFeign的调用。这种调用中,调用者发起请求后需要等待服务提供者执行业务返回结果后,才能继续执行后面的业务。也就是说调用者在调用…

五大开放式耳机推荐,选对耳机让运动更带感!

看似精彩的户外运动经历背后,其实是枯燥的体能运动和训练,以及独自长途和长时间旅行伴随的孤独感,而排解这些不良情绪的最佳方式就是音乐。如果你希望在运动、舒适、安全和音质之间获得一个最佳平衡,那相比入耳式耳机,…

进迭时空宣布开源RISC-V芯片的AI核心技术

仟江水商业电讯(4月29日 北京 委托发布)4月29日,在“创芯生生不息——进迭时空2024年度产品发布会”上,进迭时空CEO、创始人,陈志坚博士宣布将开源进迭时空在自研RISC-V AI CPU上的核心技术,包括AI扩展指令…

iOS 实现视图遮罩效果

有时候,我们会遇到这种需求,只讲视图的某个部分展示出来 这时候,我们可以通过设置该视图layer.mask layerb来实现,需要注意的是,这里的layerb必须要设置backgroundColor,渐变layer有colors,否则达不到效果…

redis ZRANGE 使用最详细文档

环境: redis_version:7.2.2 本文参考 redis 官方文档1 语法 ZRANGE key start stop [BYSCORE | BYLEX] [REV] [LIMIT offset count] [WITHSCORES]参数含义key是有序集合的键名start stop在不同语境下,可用值不一样BYSCORE | BYLEX按照分数查询 | 相…

Momentum Contrast (MoCo) for Unsupervised Visual Representation Learning

1 Introduction 1.1 Instance discrimination (样本判别) 制定了一种划分正样本和负样本的规则 1.2 InfoNCE Loss 1.3 Momentum 动量在数学上可以理解为是一种指数移动平均(Exponential Moving Average) \(m\)为动量系数,目的是为了 \(Y_t\) 不仅仅依赖于当前时刻的输入 \(X_t…

2.顺序表_链表(附练习)

目录 1.线性表 2.顺序表 2.1概念及结构 2.2 接口实现 2.3 顺序表的问题及思考 3.链表 3.1 链表的概念及结构 3.2 链表的分类 3.3 链表的实现 3.4 链表面试题 3.5 双向链表的实现 4.顺序表和链表的区别 1.线性表 线性表(linear list)是n个具…

OPPO A72/A55/K7X/A53真我Q3S等手机ROOT刷机后广电卡没信号不读卡解决办法

目前运营商除了移动联通电信以外,还存在1个中国广电,广电属于第四大运营商,由于广电起步较晚,对于手机频段要求也自然不一样,导致目前市面上部分手机出厂没有信号或者不读卡等问题,特别在手机被用户自行刷机…

前端开发攻略---用原生JS在网页中也能实现语音识别

1、语音识别的过程 语音识别涉及三个过程:首先,需要设备的麦克风接收这段语音;其次,语音识别服务器会根据一系列语法 (基本上,语法是你希望在具体的应用中能够识别出来的词汇) 来检查这段语音;最后&#xf…

Django后台项目开发实战一

开发环境使用 Anaconda, IDE 使用 pycharm 第一阶段 创建 Django 项目 在 Anaconda Prompt 中逐步输入下面的命令(之后的所有命令都在这个) 首先创建一个虚拟环境,名称自拟,python 版本我这里使用 3.9.18 关于 python 版本和…

llama-factory/peft微调千问1.5-7b-chat

目标 使用COIG-CQIA数据集和通用sft数据集对qwen1.5-7b-chat进行sft微调,使用公开dpo数据集进行dpo对齐。学习千问的长度外推方法。 一、训练配置 使用Lora方式, 将lora改为full即可使用全量微调。 具体的参数在 该框架将各个参数、训练配置都封装好了,直接使用脚本,将数…

如何下载AndroidStudio旧版本

文章目录 1. Android官方网站2. 往下滑找到历史版本归档3. 同意软件下载条款协议4. 下载旧版本Androidstudio1. Android官方网站 点击 Android官网AS下载页面 https://developer.android.google.cn/studio 进入AndroidStuido最新版下载页面,如下图: 2. 往下滑找到历史版本归…

如何解决DA14531编译工程出现大量报错的问题

在编译DA14531某个工程时,在这台电脑可以编译,另外一台电脑就编译不过,出现很多错误问题。那要怎样处理呢? 建议安装新MDK版本 可能是MDK版本问题,在不同的电脑安装不同的MDK版本,用新的版本可以编译通过&…

WORD排版常见问题与解决方案

前言 近期使用word软件进行论文排版工作,遇到了一些常见的问题,记录一下,避免遗忘。 基本配置 系统环境:win10/win11 word版本:Microsoft Office LTSC 专业增强版 2021 问题与解决方案 问题1:页眉显示内…