当前位置: 首页 > 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;访问…...

在ubuntu开发机上体验taotoken分钟级接入多种大模型的过程

&#x1f680; 告别海外账号与网络限制&#xff01;稳定直连全球优质大模型&#xff0c;限时半价接入中。 &#x1f449; 点击领取海量免费额度 在 Ubuntu 开发机上体验 Taotoken 分钟级接入多种大模型的过程 1. 准备工作与环境确认 在开始之前&#xff0c;我使用的是一台运行…...

IPXWrapper完整教程:让经典游戏在Windows 10/11重获联机能力

IPXWrapper完整教程&#xff1a;让经典游戏在Windows 10/11重获联机能力 【免费下载链接】ipxwrapper 项目地址: https://gitcode.com/gh_mirrors/ip/ipxwrapper 还在为《星际争霸》《帝国时代》等经典游戏无法在现代Windows系统上联机而烦恼吗&#xff1f;IPXWrapper正…...

Sobolev学习代理加速优化:激活函数与径向基函数选择鲁棒性分析

1. 项目概述与核心思路在工程优化和科学计算领域&#xff0c;我们常常会遇到一个令人头疼的问题&#xff1a;目标函数的每一次评估都极其昂贵。比如&#xff0c;一次评估可能意味着运行一次耗时数小时的流体力学仿真&#xff0c;或者调用一次复杂的有限元分析。传统的无导数优化…...

GPT-SoVITS终极指南:如何用1分钟语音克隆任何人的声音

GPT-SoVITS终极指南&#xff1a;如何用1分钟语音克隆任何人的声音 【免费下载链接】GPT-SoVITS 1 min voice data can also be used to train a good TTS model! (few shot voice cloning) 项目地址: https://gitcode.com/GitHub_Trending/gp/GPT-SoVITS 在人工智能语音…...

忘记压缩包密码怎么办?3个步骤帮你快速找回加密文件访问权限

忘记压缩包密码怎么办&#xff1f;3个步骤帮你快速找回加密文件访问权限 【免费下载链接】ArchivePasswordTestTool 利用7zip测试压缩包的功能 对加密压缩包进行自动化测试密码 项目地址: https://gitcode.com/gh_mirrors/ar/ArchivePasswordTestTool 你是否曾经面对一个…...

023、PCB设计软件选择与安装(Altium Designer)

023、PCB设计软件选择与安装(Altium Designer) 从一块烧掉的板子说起 去年冬天,我接手一个同事离职留下的项目——一块四层板的电机驱动板。原理图看着没问题,Layout也走通了,打样回来上电,MOS管直接冒烟。排查三天,最后发现是电源回路的地线回流路径被一根细长的走线…...

Thorium浏览器:基于Chromium的终极性能优化与隐私保护深度解析

Thorium浏览器&#xff1a;基于Chromium的终极性能优化与隐私保护深度解析 【免费下载链接】thorium Chromium fork named after radioactive element No. 90. Source code and Linux releases. Windows/MacOS/ARM builds served in different repos, links are towards the to…...

5步解决Windows包管理器Winget安装难题:专业修复指南

5步解决Windows包管理器Winget安装难题&#xff1a;专业修复指南 【免费下载链接】winget-install Install WinGet using PowerShell! Prerequisites automatically installed. Works on Windows 10/11 and Server 2019/2022. 项目地址: https://gitcode.com/gh_mirrors/wi/w…...

别再为单细胞数据批次效应发愁了!手把手教你用Harmony算法搞定整合分析(附Seurat实战代码)

单细胞数据整合实战&#xff1a;用Harmony算法高效消除批次效应当我们面对来自不同实验室、不同测序平台或不同实验条件的单细胞RNA测序数据时&#xff0c;一个无法回避的挑战就是批次效应。这种技术性变异会掩盖真实的生物学差异&#xff0c;导致细胞聚类混乱、跨样本比较失效…...

AI产业到底包括哪些

AI 产业是一条从能源 / 材料→算力基建→数据→算法框架→大模型→平台服务→行业应用→终端与具身智能的完整长链&#xff0c;每一层环环相扣、层层驱动。下面从头到尾完整描述。一、最底层&#xff1a;能源与基础材料&#xff08;产业根基&#xff09;AI 是极度耗能的产业&am…...