当前位置: 首页 > news >正文

.netcore grpc服务端流方法详解

一、服务端流式处理概述

  1. 客户端向服务端发送请求,服务端可以将多个消息流式传输回调用方
  2. 和客户端流相反,客户端流发出请求,服务端可以传输一批消息给客户端,直至本次请求响应完全结束。
  3. 针对文件分段传输下载,该方式非常有用。

二、案例介绍

  1. 提供一个一元方法查询文件
  2. 提供一个文件流传输的服务端流式方法,进行文件流推送

三、服务端配置(注意:grpc相关配置参考我之前的文章)

// 1.提供公共的实体proto文件
// 2.服务引用对应的proto文件
// 3.定义三个客户流方法syntax = "proto3";option csharp_namespace = "GrpcProject";package grpc.serviceing;// 服务端流对应的请求流和响应流message FileInfoRequest
{string fileName = 1;
}message FileInfoResponse
{string fileName = 1;int64 fileSize = 2;string extension = 3;
}message ProgressBarResponse
{FileInfoResponse fileMessage = 1;bytes fileBytes = 2;
}// serverstream.proto定义service方法syntax = "proto3";import "google/protobuf/empty.proto";
import "Protos/messages.proto";option csharp_namespace = "GrpcProject";package grpc.serviceing;service ServerStreamRpc{// 一元文件获取展示rpc GetFileMessage(google.protobuf.Empty) returns (FileInfoResponse);// 服务端文件流处理rpc StreamingFromServer	(FileInfoRequest) returns (stream ProgressBarResponse);
}

服务接口实现:

    public class ServerStreamService : ServerStreamRpc.ServerStreamRpcBase{/// <summary>/// 获取文件信息/// </summary>/// <param name="request">空请求</param>/// <param name="context">服务调用上下文</param>/// <returns></returns>public override Task<FileInfoResponse> GetFileMessage(Empty request, ServerCallContext context){var filePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Files", "cn-Liang-y.rar");FileInfo fileInfo = new FileInfo(filePath);FileInfoResponse fileInfoResponse = new FileInfoResponse();fileInfoResponse.FileName = fileInfo.Name;fileInfoResponse.FileSize = fileInfo.Length;fileInfoResponse.Extension = fileInfo.Extension;return Task.FromResult(fileInfoResponse);}public override async Task StreamingFromServer(FileInfoRequest request,IServerStreamWriter<ProgressBarResponse> responseStream,ServerCallContext context){var filePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Files", request.FileName);if (!File.Exists(filePath)){throw new FileNotFoundException(nameof(filePath));}// 进度条按照 100百分比进行划分FileInfo fileInfo = new FileInfo(filePath);using var fileStream = fileInfo.OpenRead();// 插入固定长度int fixedLength = (int)fileStream.Length / 100;byte[] fileBytes = new byte[fixedLength];int len;while ((len = fileStream.Read(fileBytes, 0, fixedLength)) > 0){await Console.Out.WriteLineAsync($"打印字节长度:{len}");var response = new ProgressBarResponse();response.FileMessage = new FileInfoResponse{FileName = fileInfo.Name,FileSize = fileInfo.Length,Extension = fileInfo.Extension};response.FileBytes = ByteString.CopyFrom(fileBytes);await responseStream.WriteAsync(response);}}}

Program注入:

    public class Program{public static void Main(string[] args){var builder = WebApplication.CreateBuilder(args);builder.Services.AddGrpc();var app = builder.Build();// 一元方法//app.MapGrpcService<DollarService>();// 客户端流//app.MapGrpcService<ClientStreamService>();// 服务端流app.MapGrpcService<ServerStreamService>();app.Run();}}

四、客户端配置

  1. 引用proto文件,配置为客户端类型
  2. 根据编译生成的函数进行传参调用
  3. 创建WPF客户端提供控制条显示

 button按钮触发grpc

        private async void download_Click(object sender, RoutedEventArgs e){Action<int> action = async i =>{progressBar.Value = i;await Task.Delay(100);};await WpfClient.Show(action);}

grpc客户端接口调用

    public class WpfClient{public static async Task Show(Action<int> action){var channel = GrpcChannel.ForAddress("https://localhost:7188");var client = new GrpcProject.ServerStreamRpc.ServerStreamRpcClient(channel);var fileMessage = await client.GetFileMessageAsync(new Google.Protobuf.WellKnownTypes.Empty());FileInfoRequest request = new FileInfoRequest();request.FileName = fileMessage.FileName;var streaming = client.StreamingFromServer(request);var path = Path.Combine(Directory.GetCurrentDirectory(), "test.rar");using var stream = new FileStream(path, FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.ReadWrite);int i = 0;await foreach (var item in streaming.ResponseStream.ReadAllAsync()){stream.Write(item.FileBytes.Span);action(i++);}stream.Flush();stream.Close();}}

五、执行结果

 在文件根目录可以看到下载的文件

 六、源码地址

链接:https://pan.baidu.com/s/13_AEFHLLJS5qN8aIby8IsA 
提取码:72x0

相关文章:

.netcore grpc服务端流方法详解

一、服务端流式处理概述 客户端向服务端发送请求&#xff0c;服务端可以将多个消息流式传输回调用方和客户端流相反&#xff0c;客户端流发出请求&#xff0c;服务端可以传输一批消息给客户端&#xff0c;直至本次请求响应完全结束。针对文件分段传输下载&#xff0c;该方式非…...

python爬虫数据解析xpath、jsonpath,bs4

数据的解析 解析数据的方式大概有三种 xpathJsonPathBeautifulSoup xpath 安装xpath插件 打开谷歌浏览器扩展程序&#xff0c;打开开发者模式&#xff0c;拖入插件&#xff0c;重启浏览器&#xff0c;ctrlshiftx&#xff0c;打开插件页面 安装lxml库 安装在python环境中的Scri…...

go语言的database/sql结合squirrel工具sql生成器完成数据库操作

database/sql database/sql是go语言内置数据库引擎&#xff0c;使用sql查询数据库&#xff0c;配置datasource后使用其数据库操作方法对数据库操作&#xff0c;如下&#xff1a; package mainimport ("database/sql""fmt"_ "github.com/Masterminds…...

LVS集群和分布式

LVS 一.集群和分布式概念 1.1 集群 在计算机领域&#xff0c;集群早在 1960 年就出现&#xff0c;随着互联网和计算机相关技术的发展&#xff0c;现在 集群这一技术已经在各大互联网公司普及。 1.1.1 集群概念 计算机集群指一组通过计算机网络连接的计算机&#xff0c;它们…...

使用QT可视化设计对话框详细步骤与代码

一、创建对话框基本步骤 创建并初始化子窗口部件把子窗口部件放到布局中设置tab键顺序建立信号-槽之间的连接实现对话框中的自定义槽 首先前面三步在这里是通过ui文件里面直接进行的&#xff0c;剩下两步则是通过代码来实现 二、项目创建详细步骤 创建新项目 为项目命名 为…...

TFTP Server

简介 TFTP&#xff08;Trivial File Transfer Protocol,简单文件传输协议&#xff09;是TCP/IP协议族中的一个用来在客户机与服务器之间进行简单文件传输的协议&#xff0c;提供不复杂、开销不大的文件传输服务。端口号为69。 TFTP和FTP的区别 安全性区别 FTP支持登录安全&…...

登录验证码实现

Hutool代码改造 Hutool 有参考文档&#xff1b;很多工具类&#xff1b;把一些功能都封装好&#xff1b;都不用你自己去写&#xff1b;直接调用它的工具类 它这里会详细告诉你引入方式Hutool <dependency><groupId>cn.hutool</groupId><artifactId>hu…...

2. 获取自己CSDN文章列表并按质量分由小到大排序(文章质量分、博客质量分、博文质量分)(阿里云API认证)

文章目录 写在前面步骤打开CSDN质量分页面粘贴查询文章url按F12打开调试工具&#xff0c;点击Network&#xff0c;点击清空按钮点击查询是调了这个接口https://bizapi.csdn.net/trends/api/v1/get-article-score用postman测试调用这个接口&#xff08;不行&#xff0c;认证不通…...

在Windows和MacOS环境下实现批量doc转docx,xls转xlsx

一、引言 Python中批量进行办公文档转化是常见的操作&#xff0c;在windows状态下我们可以利用changeOffice这个模块很快进行批量操作。 二、在Windows环境下的解决文案 Windows环境下&#xff0c;如何把doc转化为docx&#xff0c;xls转化为xlsx&#xff1f; 首先&#xff…...

【网络编程(二)】NIO快速入门

NIO Java NIO 三大核心组件 Buffer&#xff08;缓冲区&#xff09;&#xff1a;每个客户端连接都会对应一个Buffer&#xff0c;读写数据通过缓冲区读写。Channel&#xff08;通道&#xff09;&#xff1a;每个channel用于连接Buffer和Selector&#xff0c;通道可以进行双向读…...

【Vue-Router】嵌套路由

footer.vue <template><div><router-view></router-view><hr><h1>我是父路由</h1><div><router-link to"/user">Login</router-link><router-link to"/user/reg" style"margin-left…...

MySQL索引总结

MySQL索引总结 1.索引的概念、作用与使用场景 本质上就是减少读写磁盘的次数。 索引是一种特殊的文件&#xff0c;包含这对数据表中所有记录的引用指针&#xff0c;可以对表中的一列或多列创建索引&#xff0c;并指定索引的类型&#xff0c;每种类型都有对应数据结构实现。 …...

谷粒商城第十二天-基本属性销售属性管理功能的实现

目录 一、总述 二、前端部分 三、后端部分 四、总结 一、总述 前端的话&#xff0c;依旧是直接使用老师给的。 前端的话还是那些增删改查&#xff0c;业务复杂一点的话&#xff0c;无非就是设计到多个字段多个表的操作&#xff0c;当然这是后端的事了&#xff0c;前端这里…...

利用安全区域的概念解决移动端兼容不同手机刘海的问题

移动端 安全区 在做移动端的项目时&#xff0c;由于不同的手机设备设置的不同&#xff0c;有些手机在上方有刘海的设计&#xff0c;我们需要做适配&#xff0c;即把想要展示的内容放在安全区域内展示。 1.自定义导航栏 在pages.json中修改如下配置 {"path":"…...

数据结构---图

这里写目录标题 图的基本概念和术语基本概念和术语1基本概念和术语2 图的类型定义抽象数据类型定义二级目录二级目录 一级目录二级目录二级目录二级目录二级目录二级目录二级目录 图的基本概念和术语 基本概念和术语1 V代表顶点的有穷非空集合 E代表边的有穷集合 n为顶点 有向…...

励志长篇小说《周兴和》书连载之十八 内外交困搞发明

内外交困搞发明 路灯发出昏黄而惺忪的光影。 周兴和疲惫地从车间出来&#xff0c;拖着沉重的腿爬上几级石阶&#xff0c;准备回到家里去。可走到家门口&#xff0c;他想了想&#xff0c;又折了回去&#xff0c;在车间的一条长条椅子上&#xff0c;他用一块试验用的废料当枕头&…...

web基础入门和php语言基础入门 二

web基础入门和php语言基础入门 二 MySQL入门-续MySQL之数据查询操作MySQL其他知识点 php语言基础入门认识PHPPHP的工作流程安装PHP环境认识一个PHP程序PHP基础知识点进入正题 PHP与WEB交互PHP与MySQL交互总结 MySQL入门-续 MySQL之数据查询操作 WHERE 子句&#xff0c;条件限…...

typeScript 之 Array

工具: PlayGround 源码&#xff1a;GitHub TypeScript 数组简介 在TypeScript中&#xff0c; 使用[]表示数组&#xff0c; 它的结构&#xff1a;let valus: 类型名[] 数据; // 数字 let numList: number[] [1, 2, 3]; // 字符串 let strList: string[] ["hello"…...

【题解】二叉树的前中后遍历

文章目录 二叉树的前序遍历二叉树的中序遍历二叉树的后序遍历 二叉树的前序遍历 题目链接&#xff1a;二叉树的前序遍历 解题思路1&#xff1a;递归 代码如下&#xff1a; void preorder(vector<int>& res, TreeNode* root){if(root nullptr) return;//遇到空节点…...

文件操作/IO

文件 文件是一种在硬盘上存储数据的方式&#xff0c;操作系统帮我们把硬盘的一些细节都封装起来了&#xff0c;程序员只需要了解文件相关的接口即可&#xff0c;相当于操作文件就是间接的操作硬盘了 硬盘用来存储数据&#xff0c;和内存相比硬盘的存储空间更大&#xff0c;访问…...

OpenClaw如何做好记忆持久化的 · 三、一条记忆的完整生命旅程

三、一条记忆的完整生命旅程⏱ 30 秒速览 | 记忆有 3 条路径&#xff1a;路径 A&#xff08;自动提取&#xff09; 噪声过滤 → Smart Extraction 六类分类 → 两阶段去重 → 向量存储 → 8 步混合检索&#xff08;ANN BM25 Cross-Encoder Weibull 衰减&#xff09;→ 智能遗…...

风冷机房温湿度数据采集解决方案

对部分气候干旱的地区来说&#xff0c;使用风冷技术对数据机房进行冷却是比较合适的方案&#xff0c;但高能耗问题仍需要避免与管控&#xff0c;要求环境温湿度与散热效率进行合理分配。对此&#xff0c;物通博联提供温湿度数据采集到机房管理平台的解决方案。 需求如下 温湿度…...

课堂行为及状态检测数据集11697张VOC+YOLO格式

课堂行为及状态检测数据集11697张VOCYOLO格式数据集格式&#xff1a;Pascal VOC格式YOLO格式(不包含分割路径的txt文件&#xff0c;仅仅包含jpg图片以及对应的VOC格式xml文件和yolo格式txt文件) 图片数量(jpg文件个数)&#xff1a;11697 标注数量(xml文件个数)&#xff1a;1169…...

终极解析器构建指南:Ohm从CSV解析到自定义语法实战

终极解析器构建指南&#xff1a;Ohm从CSV解析到自定义语法实战 【免费下载链接】ohm A library and language for building parsers, interpreters, compilers, etc. 项目地址: https://gitcode.com/gh_mirrors/oh/ohm Ohm是一个强大的解析器构建库和领域特定语言&#…...

最好用的服务器文件传输工具:SSHFerry(下载见结尾)

为了 AutoDL 传文件更快更省心&#xff0c;我自己做了个 SSH 工作区&#xff1a;SSHFerry&#xff08;下载见结尾&#xff09; 之前我写过一篇和 AutoDL 上传有关的文章&#xff0c;没想到后面慢慢有了 1 万多阅读。 但那篇文章现在回头看&#xff0c;我觉得还是有点不够负责。…...

TA6585替代品6586直流双向电机驱动芯片详解

在电机驱动领域&#xff0c;芯片的性能、稳定性与适配性决定着设备的运行效果与使用寿命。6586作为TA6585的替代品&#xff0c;是一款高性能直流双向电机驱动芯片&#xff0c;凭借其小巧的封装、全面的保护功能及广泛的适配场景&#xff0c;替代TA6585&#xff0c;成为玩具、智…...

连锁经营行业商旅平台选型指南与测评排名Top 6:多门店与全链路商旅管控方案

2026年4月的第一周&#xff0c;艾美咨询发布了《2026年中国连锁经营行业商旅管理数字化白皮书》&#xff0c;数据显示国内规模以上连锁经营企业的商旅支出占整体运营成本的8.7%&#xff0c;其中私车公用、门店巡检类商旅的合规漏洞造成的浪费占总商旅支出的19.2%&#xff0c;连…...

当你的手柄在Windows上“水土不服“时,内核级虚拟化如何解决问题?

当你的手柄在Windows上"水土不服"时&#xff0c;内核级虚拟化如何解决问题&#xff1f; 【免费下载链接】ViGEmBus Windows kernel-mode driver emulating well-known USB game controllers. 项目地址: https://gitcode.com/gh_mirrors/vi/ViGEmBus 你是否曾经…...

Speechless:如何用一款免费Chrome插件永久保存你的微博记忆

Speechless&#xff1a;如何用一款免费Chrome插件永久保存你的微博记忆 【免费下载链接】Speechless 把新浪微博的内容&#xff0c;导出成 PDF 文件进行备份的 Chrome Extension。 项目地址: https://gitcode.com/gh_mirrors/sp/Speechless 在数字时代&#xff0c;我们的…...

GHelper完整指南:免费轻量级华硕笔记本性能控制工具终极教程

GHelper完整指南&#xff1a;免费轻量级华硕笔记本性能控制工具终极教程 【免费下载链接】g-helper Lightweight, open-source control tool for ASUS laptops and ROG Ally. Manage performance modes, fans, GPU, battery, and RGB lighting across Zephyrus, Flow, TUF, Str…...