How to configure GRPC by vcpkg and visual studio 2022?

     之前装了visual studio 2019, 运行客户demo,发现使用的visual studio 2022上的grpc库版本,所以又升级安装了vs2022,由于之前已经安装了grpc(基于vs2019 MSVC库),由于grpc版本是由不同的msbuild(visual studio)的MSVC库的版本决定的。所以决定删除掉老的grpc库(vs2019 msvc库),去安装新版本的grpc库(基于vs2022 MSVC库),但移除老grpc库,试了指定vcpkg中grpc port的方法请参考文章vcpkg安装指定版本的库_vcpkg 指定版本-优快云博客,但安装指定版本库时会报错,后来又尝试解决报错,请参考文章2024最新版Vcpkg安装第三方库报错error: building XXXX failed with: BUILD_FAILED_build version: 1.0.3 build date: 2024-05-18 14:06:-优快云博客

尝试多次无果,索性把整个vcpkg目录删除,重新配置vcpkg,再下载grpc lib。

使用清单文件加载依赖文件到项目的做法,请参考文章:vcpkg 从清单文件安装依赖项_vcpkg清单模式-优快云博客

本章节主要讲述怎样在本地使用vcpkg构建基于windows平台的grpc库,不考虑vcpkg的清单模式。

首先什么是vcpkg,请参考文章vcpkg 概述 | Microsoft Learn, 简单来说就是管理各种库并防止库冲突的工具,我们接下来使用它来下载grpc库。请参考在 Visual Studio 中使用 MSBuild 安装和管理包 | Microsoft Learn,这里我们只需使用先决条件的设置vcpkg 1,克隆存储库 2.运行启动脚本,3.与 Visual Studio MSBuild 集成,这里不讨论使用清单模式。其中第2步运行启动脚本,由于网络原因,下载vcpkg.exe会比较慢,经常出现失败的情况,大家可以把最新自己独立下载的vcpkg.exe拷贝到vcpkg目录下,同时也要把vcpkgTools.xml拷贝到vcpkg\scripts目录下。vcpkg安装完成,接下来需要设置vcpkg的环境变量,设置名为VCPKG_ROOT的环境变量,内容是d:\vcpkg。然后就可以安装grpc库了,首先打开visual studio 2022工程文件,选择tools->command line->Developer PowerShell,界面如图1所示:在当前目录下输入命令 vcpkg install grpc:x64-windows,第一次提示:找不到vcpkg\scripts\vcpkgTools.xml,由于网速差,我不是下载的vcpkg.exe,所以也需要拷贝vcpkgTools.xml这个文件到scripts目录下,再次执行命令vcpkg install grpc:x64-windows,成功开始安装了,除了安装grpc的包,还会安装protobuf的包,还有cmake的包,这些lib在这个命令中会统一安装完成,这个过程比较耗时,需要二三十分钟这个样子。

图1

安装过程中,网络状况依然不好,如图2所示,出现好几次buid failed,所以需要重新输入命令:vcpkg install grpc:x64-windows

                                                                         图2

中间重试了两次安装命令后,最后安装完成了,参见图3。

图3

然后在项目属性中配置上lib, include文件夹,位于D:\vcpkg\installed\x64-window下,具体配置lib及dll的详情,请参考VS 中 c++ 工程添加 lib 库 dll 库及头文件的步骤_vs c++ 使用.lib dll-优快云博客,配置完毕后,rebuild整个项目,如果没有配置缓存,每次rebuild grpc lib需要半个小时左右,请耐心等visual studio 2022编译完成,然后程序就可以启动了。

大文件分片下载是一种常见的下载方式,可以通过将大文件分成多个小文件下载,从而提高下载速度稳定性。在 Vue SpringBoot 中,可以通过以下步骤实现大文件分片下载: 1.大文件分成多个小文件,每个小文件大小为固定的值,比如1MB或2MB。 2.前端 Vue 中,使用 axios 发送请求,并设置请求头 Range,表示请求文件的某个片段。 3.后端 SpringBoot 中,接收前端请求,并根据请求头 Range,返回对应的文件片段。 4. 前端 Vue 接收到多个文件片段后,将它们合并成一个完整的文件。 5. 下载完成后,将多个小文件删除,以释放存储空间。 具体实现细节可以参考以下代码: 前端 Vue: ``` downloadFile() { const url = '/api/download'; const file_name = 'large_file.mp4'; const chunk_size = 2 * 1024 * 1024; // 2MB per chunk const total_size = 1024 * 1024 * 1024; // 1GB const total_chunks = Math.ceil(total_size / chunk_size); const headers = { 'Content-Type': 'application/json' }; axios.post(url, { file_name, chunk_size, total_size }, { headers }) .then(res => { const { data } = res; const blobs = data.map((chunk, index) => { return new Blob([chunk], { type: 'application/octet-stream' }); }); const blob = new Blob(blobs, { type: 'application/octet-stream' }); const object_url = window.URL.createObjectURL(blob); const link = document.createElement('a'); link.href = object_url; link.download = file_name; link.click(); window.URL.revokeObjectURL(object_url); }); } ``` 后端 SpringBoot: ``` @PostMapping("/download") public List<byte[]> downloadFile(@RequestBody Map<String, Object> params, HttpServletRequest request, HttpServletResponse response) throws IOException { String file_name = (String) params.get("file_name"); int chunk_size = (int) params.get("chunk_size"); int total_size = (int) params.get("total_size"); int total_chunks = (int) Math.ceil((double) total_size / chunk_size); String range_header = request.getHeader("Range"); if (range_header == null) { response.setStatus(HttpServletResponse.SC_BAD_REQUEST); return null; } String[] range = range_header.split("=")[1].split("-"); int start = Integer.parseInt(range[0]); int end = range.length > 1 ? Integer.parseInt(range[1]) : start + chunk_size - 1; if (end >= total_size) { end = total_size - 1; } response.setHeader("Content-Type", "application/octet-stream"); response.setHeader("Content-Length", String.valueOf(end - start + 1)); response.setHeader("Content-Range", "bytes " + start + "-" + end + "/" + total_size); response.setHeader("Accept-Ranges", "bytes"); response.setStatus(HttpServletResponse.SC_PARTIAL_CONTENT); RandomAccessFile file = new RandomAccessFile(file_name, "r"); file.seek(start); byte[] bytes = new byte[chunk_size]; List<byte[]> chunks = new ArrayList<>(); int read = 0; while (read < chunk_size && start + read <= end) { int n = file.read(bytes, read, chunk_size - read); if (n <= 0) { break; } read += n; } chunks.add(Arrays.copyOf(bytes, read)); file.close(); return chunks; } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值