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

树莓派超全系列教程文档--(62)使用rpicam-app通过网络流式传输视频

使用rpicam-app通过网络流式传输视频 使用 rpicam-app 通过网络流式传输视频UDPTCPRTSPlibavGStreamerRTPlibcamerasrc GStreamer 元素 文章来源&#xff1a; http://raspberry.dns8844.cn/documentation 原文网址 使用 rpicam-app 通过网络流式传输视频 本节介绍来自 rpica…...

工业安全零事故的智能守护者:一体化AI智能安防平台

前言&#xff1a; 通过AI视觉技术&#xff0c;为船厂提供全面的安全监控解决方案&#xff0c;涵盖交通违规检测、起重机轨道安全、非法入侵检测、盗窃防范、安全规范执行监控等多个方面&#xff0c;能够实现对应负责人反馈机制&#xff0c;并最终实现数据的统计报表。提升船厂…...

智慧工地云平台源码,基于微服务架构+Java+Spring Cloud +UniApp +MySql

智慧工地管理云平台系统&#xff0c;智慧工地全套源码&#xff0c;java版智慧工地源码&#xff0c;支持PC端、大屏端、移动端。 智慧工地聚焦建筑行业的市场需求&#xff0c;提供“平台网络终端”的整体解决方案&#xff0c;提供劳务管理、视频管理、智能监测、绿色施工、安全管…...

Nginx server_name 配置说明

Nginx 是一个高性能的反向代理和负载均衡服务器&#xff0c;其核心配置之一是 server 块中的 server_name 指令。server_name 决定了 Nginx 如何根据客户端请求的 Host 头匹配对应的虚拟主机&#xff08;Virtual Host&#xff09;。 1. 简介 Nginx 使用 server_name 指令来确定…...

C#中的CLR属性、依赖属性与附加属性

CLR属性的主要特征 封装性&#xff1a; 隐藏字段的实现细节 提供对字段的受控访问 访问控制&#xff1a; 可单独设置get/set访问器的可见性 可创建只读或只写属性 计算属性&#xff1a; 可以在getter中执行计算逻辑 不需要直接对应一个字段 验证逻辑&#xff1a; 可以…...

Java数值运算常见陷阱与规避方法

整数除法中的舍入问题 问题现象 当开发者预期进行浮点除法却误用整数除法时,会出现小数部分被截断的情况。典型错误模式如下: void process(int value) {double half = value / 2; // 整数除法导致截断// 使用half变量 }此时...

AI+无人机如何守护濒危物种?YOLOv8实现95%精准识别

【导读】 野生动物监测在理解和保护生态系统中发挥着至关重要的作用。然而&#xff0c;传统的野生动物观察方法往往耗时耗力、成本高昂且范围有限。无人机的出现为野生动物监测提供了有前景的替代方案&#xff0c;能够实现大范围覆盖并远程采集数据。尽管具备这些优势&#xf…...

【Linux】Linux 系统默认的目录及作用说明

博主介绍&#xff1a;✌全网粉丝23W&#xff0c;CSDN博客专家、Java领域优质创作者&#xff0c;掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域✌ 技术范围&#xff1a;SpringBoot、SpringCloud、Vue、SSM、HTML、Nodejs、Python、MySQL、PostgreSQL、大数据、物…...

深入浅出Diffusion模型:从原理到实践的全方位教程

I. 引言&#xff1a;生成式AI的黎明 – Diffusion模型是什么&#xff1f; 近年来&#xff0c;生成式人工智能&#xff08;Generative AI&#xff09;领域取得了爆炸性的进展&#xff0c;模型能够根据简单的文本提示创作出逼真的图像、连贯的文本&#xff0c;乃至更多令人惊叹的…...

springboot 日志类切面,接口成功记录日志,失败不记录

springboot 日志类切面&#xff0c;接口成功记录日志&#xff0c;失败不记录 自定义一个注解方法 import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target;/***…...