.netcore grpc服务端流方法详解

news2024/11/25 5:02:39

一、服务端流式处理概述

  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

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

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

相关文章

ssm基于Java ssm的校园驿站管理系统源码和论文

ssm基于Java ssm的校园驿站管理系统源码和论文016 开发工具&#xff1a;idea 数据库mysql5.7 数据库链接工具&#xff1a;navcat,小海豚等 技术&#xff1a;ssm 摘 要 互联网发展至今&#xff0c;无论是其理论还是技术都已经成熟&#xff0c;而且它广泛参与在社会中的方…

铁是地球科学争论的核心

一项新的研究调查了地球内部铁的形态。这些发现对理解内核的结构产生了影响。 一项新的研究探索了地球内核的铁结构&#xff0c;如图中的黄色和白色所示。 资料来源&#xff1a;地球物理研究快报 地球内核以铁为主&#xff0c;铁可以多种晶体形式作为固体材料存在。&#xff08…

K8S系列三:单服务部署

写在前面 本文是K8S系列第三篇&#xff0c;主要面向对K8S新手同学&#xff0c;阅读本文需要读者对K8S的基本概念&#xff0c;比如Pod、Deployment、Service、Namespace等基础概念有所了解。尚且不熟悉的同学推荐先阅读本系列的第一篇文章《K8S系列一&#xff1a;概念入门》[1]…

如何读取文件夹内的诸多文件,并选择性的保留部分文件

目录 问题描述: 问题解决: 问题描述: 当前有一个二级文件夹,第一层是文件夹名称是“Papers(LNAI14302-14304)",第二级文件夹目录名称如下图蓝色部分所示。第三层为存放的文件,如下下图所示,每一个文件中,均存放三个文件,分别为copyright.pdf, submission.pdf, s…

【CSS】禁用元素鼠标事件(例如实现元素禁用效果)

文章目录 基本用法 基本用法 pointer-events 属性指定在什么情况下 (如果有) 某个特定的图形元素可以成为鼠标事件。实际运用中可以通过对auto 和none动态控制&#xff0c;来动态实现元素的禁用效果。 属性描述auto与pointer-events属性未指定时的表现效果相同&#xff0c;对…

对方发送的文件已过期如何恢复,这样做很简单

我们常常使用微信来发送文件、传输文件&#xff0c;但很多人也会遇到文件过期的情况。每当发现文件已过期&#xff0c;都会懊恼自己当初为什么没有早点下载保存。 大家要知道&#xff0c;微信文件如果7天内没有及时下载是会被清理的。不过&#xff0c;大家不要着急&#xff0c…

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

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

这些款式多样的运动式蓝牙耳机哪种好?看完你就懂了

正所谓运动式蓝牙耳机是专为运动而生的&#xff0c;运动时戴上耳机&#xff0c;再来点动感、或舒缓的音乐&#xff0c;提高我们运动的效率。运动式耳机比普通的蓝牙耳机更加的适合在运动中使用&#xff0c;而纵观当下耳机市场&#xff0c;运动式的蓝牙耳机众多&#xff0c;各类…

​比特丛林用量子纠缠对抗高智商犯罪

世界上没有绝对完美的犯罪&#xff0c;但是预谋和统筹良久的高智商犯罪都几乎接近于完美和无比烧脑。 警局的洽谈室&#xff0c;只有我和嫌疑人两个人。 各自坐在桌子两边&#xff0c;门已关。在这个封闭的空间里&#xff0c;我一手拿着筷子吃着盒饭&#xff0c;一边撇了一下…

MounRiver 从模板中抽取自定义自己工程

MounRiver 序言准备依赖资源工程历程建立自己工程 步骤一 资源链接步骤二步骤三 包含汇编路径步骤四 添加源文件路径步骤五 添加链接文件步骤六社区版 添加编译启动文件![请添加图片描述](https://img-blog.csdnimg.cn/10969073d7f341abafad8232cab3c16b.jpeg)专业版 序言 准…

问AI一个严肃的问题

chatgpt的问世再一次掀起了AI的浪潮&#xff0c;其实我一直在想&#xff0c;AI和人类的关系未来会怎样发展&#xff0c;我们未来会怎样和AI相处&#xff0c;AI真的会完全取代人类吗&#xff0c;带着这个问题&#xff0c;我问了下chatgpt&#xff0c;看一看它是怎么看待这个问题…

spring-boot-maven-plugin插件详解

一、 为什么Spring Boot项目自带这个插件 当我们在SpringBoot官方下载一个脚手架时,会发现pom.xml会自带spring-boot-maven-plugin插件 那为什么会自带这个插件呢&#xff1f; 我们知道Spring Boot项目&#xff0c;是可以通过java -jar 包名启动的 打包命令 mvn clean pac…

冠达管理:“股债汇”三杀!总统大选结果意外,这国汇率暴跌两成

当地时间8月14日&#xff0c;美股三大股指全线收涨&#xff0c;纳指涨超1%。本周商场重视多家重要零售商的财报与7月零售出售数据。 大型科技股大都上涨&#xff0c;英伟达低开高走涨7.09%&#xff0c;创5月26日以来最大单日涨幅&#xff0c;早盘总市值一度跌破万亿美元。摩根士…

QQ附近人引流的几个详细方法,qq附近人引流脚本实操演示教程

大家好我是你们的小编一辞脚本&#xff0c;今天给大家分享新的知识&#xff0c;很开心可以在CSDN平台分享知识给大家,很多伙伴看不到代码我先录制一下视频 在给大家做代码&#xff0c;给大家分享一下qq引流脚本的知识和视频演示 不懂的小伙伴可以认真看一下&#xff0c;我们一…

idea常见错误大全之:解决全局搜索失效+搜索条件失效(条件为空)+F8失灵

问题一&#xff1a;全局搜索快捷键ctrlshiftf 突然失灵了&#xff0c;键盘敲烂了 都没反应&#xff0c;这是为什么呢&#xff1f; 肯定不是idea本身的原因&#xff0c;那么就是其它外在因素影响到了idea的快捷键&#xff0c;那么其它的快捷键为什么没失效呢&#xff0c;原因只有…

煜邦转债,华设转债,兴瑞转债,神通转债上市价格预测

煜邦转债 基本信息 转债名称&#xff1a;煜邦转债&#xff0c;评级&#xff1a;A&#xff0c;发行规模&#xff1a;4.10806亿元。 正股名称&#xff1a;煜邦电力&#xff0c;今日收盘价&#xff1a;8.82元&#xff0c;转股价格&#xff1a;10.12元。 当前转股价值 转债面值 / …

nodejs+vue+elementui医院电子病历管理系统5a4x5

此系统任何人都可以使用&#xff0c;哪怕对代码完全不懂&#xff0c;只会电脑的基础操作并且安装这几款软件就可以对本系统进行操作&#xff0c;实现了人员使用方面的自由&#xff0c;不必有过多的限制。 语言 node.js 框架&#xff1a;Express 前端:Vue.js 数据库&#xff1a;…

安卓快速开发

1.环境搭建 Android Studio下载网页&#xff1a;https://developer.android.google.cn/studio/index.html 第一次新建工程需要等待很长时间&#xff0c;新建一个Empty Views Activity 项目&#xff0c;右上角选择要运行的机器&#xff0c;运行就安装上去了(打开USB调试)。 2…

冠达管理:融券卖出交易规则?

融券卖出买卖是指投资者在没有实际持有某只股票的情况下&#xff0c;经过借入该股票并卖出来取得赢利的一种股票买卖方式。融券卖出买卖规矩针对不同市场、不同证券公司之间可能会存在一些差异&#xff0c;但基本的规矩包含如下几个方面。 一、融资融券的资历要求 在进行融券卖…

滑模控制器理论推导和matlab/simulink实例分享

滑模控制的运动轨迹主要分为两个方面&#xff1a;(1)系统的任意初始状态向滑模面运动阶段&#xff1b;(2)系统到达滑模面后并且慢慢趋于稳定的阶段。所以&#xff0c;对于滑模变结构控制器的设计&#xff0c;对应于系统运动的两个阶段&#xff0c;可以分为两个部分&#xff1a;…