排名
1
文章
860
粉丝
112
评论
163
.net core自定义项目模板,创建自己的模板项目,使用命令行创建模板项目
尘叶心繁 : 可以可以讲真的我都想弄个模板
net core webapi post传递参数
庸人 :
确实坑哈,我也是下班好了好几次,发现后台传递对象是可以的,但...
.net webapi 返回需要的字段,忽略某些字段,修改字段名等
雨雨雨雨雨辰 : 已精
.net webapi 返回需要的字段,忽略某些字段,修改字段名等
雨雨雨雨雨辰 :
疯狂反射
百度编辑器自定义模板
庸人 : 我建议换个编辑器,因为现在百度富文本已经停止维护了,用tinymec...
ICP备案 :渝ICP备18016597号-1
网站信息:2018-2025TNBLOG.NET
技术交流:群号656732739
联系我们:contact@tnblog.net
公网安备:
50010702506256


欢迎加群交流技术

html前台,完全一样:
- <form method="post" action="/home/UpLoadImgStream" enctype="multipart/form-data">
- <input type="file" name="upfile" />
- <input type="submit" name="上传" />
- </form>
gRPC服务端
proto
- syntax = "proto3";
-
- option csharp_namespace = "GrpcService1";
-
- package UpImgStream;
-
- // The greeting service definition.
- service UpImgStream {
- // Sends a greeting
- rpc DoUpLoad (stream StreamRequest) returns (UpImgStreamReply);
- }
-
- // The request message containing the user's name.
- message StreamRequest {
- bytes content = 1;
- //文件后缀名(弃用,通过另外的方式在文件之前传递)
- string fileExt=2;
- }
-
- // The response message containing the greetings.
- message UpImgStreamReply {
- string message = 1;
- }
实现:
- public override async Task<UpImgStreamReply> DoUpLoad(IAsyncStreamReader<StreamRequest> requestStream, ServerCallContext context)
- {
- try
- {
- //获取调用方的id
- string host = context.Host;
- //if (context.UserState.ContainsKey("fileExt"))
- //{
- // object fileExt = context.UserState["fileExt"];
- //}
- //注意获取的时候用小写
- var fileExtMetadata = context.RequestHeaders.FirstOrDefault(a => a.Key == "fileext");
- if (fileExtMetadata == null)
- {
- return new UpImgStreamReply
- {
- Message = "上传失败!"
- };
- }
- string fileExt = fileExtMetadata.Value;
-
- // 新建一个文件流用于存放我们获取到数据
- using (var fs = new FileStream("c://" + Guid.NewGuid().ToString().Replace("-", "") + "." + fileExt, FileMode.Create))
- {
- while (await requestStream.MoveNext()) // 循环从流中读取数据(监听gRPC客户端的流写入)
- {
- requestStream.Current.Content.WriteTo(fs); // 将数据写入到文件流中
- }
- //数据是先被读到了内存中,再把数据写到文件中,当你数据读完的时候不代表你的数据已经写完了,因为还有一部分有可能会留在内存这个缓冲区中。这时候如果你调用了close()方法关闭了读写流,那么这部分数据就会丢失,所以应该在关闭读写流之前先flush()。
- fs.Flush();
- }
- return new UpImgStreamReply
- {
- Message = "上传成功!"
- };
- }
- catch (Exception ex)
- {
- return new UpImgStreamReply
- {
- Message = "上传失败!"
- };
- }
- }
gRPC客户端
方法一:文件分段传输
适用于文件有点点大的情况
- /// <summary>
- /// 调用gRPC 客户端流式图片上传(文件分段传输)
- /// </summary>
- public async void UpLoadImgStream(List<IFormFile> upfile)
- {
- //获取页面传递的文件流
- foreach (var formFile in upfile)
- {
- if (formFile.Length > 0)
- {
- #region 获取gRPC接口
- AppContext.SetSwitch("System.Net.Http.SocketsHttpHandler.Http2UnencryptedSupport", true);
- var channel = GrpcChannel.ForAddress("http://localhost:8099/");
- var client = new UpImgStream.UpImgStreamClient(channel);
- #endregion
-
- //获取文件的后缀名
- string fileExt = formFile.FileName.Substring(formFile.FileName.LastIndexOf('.') + 1); //文件扩展名
-
- Metadata entries = new Metadata();
- entries.Add("fileExt", fileExt);
- AsyncClientStreamingCall<StreamRequest, UpImgStreamReply> call = client.DoUpLoad(entries);//先调用服务后面在提供数据
-
- //得到文件流
- Stream stream = formFile.OpenReadStream();
-
- try
- {
- var remainingLength = stream.Length; //文件总长度
- int sendlength = 100 * 1024;//1048576;
-
- //先把分段读取的数据存储在集合里边,因为直接调用gRPC传输,第二次读取流的时候会关闭,暂时还没有解决就使用这种方法
- List<byte[]> byteList = new List<byte[]>();
-
- byte[] buff = new byte[sendlength]; // 缓冲区,这里我们设置为 nkb
- while (remainingLength > 0) // 若未读完则继续读取(把文件分为单位nkb的传递,如果小于nkb则一次传递完)
- {
- if (remainingLength < sendlength)//剩下的可以一次传递完
- {
- buff = new byte[remainingLength];
- }
-
- //注意读一次后调用WriteAsync,Stream流就关闭了,但是如果不执行WriteAsync是可以读完所有的
- int len = stream.Read(buff, 0, buff.Length); // 异步从文件中读取数据到缓冲区中
- remainingLength -= len; // 剩余长度=当前总长度-这次实际读取的长度
-
- byteList.Add(buff);
- }
-
- //分段调用gRPC流进行文件传输
- foreach (byte[] item in byteList)
- {
- //向gRPC流中写入我们刚刚读取的数据
- await call.RequestStream.WriteAsync(new StreamRequest() { Content = ByteString.CopyFrom(item) });
- }
-
- await call.RequestStream.CompleteAsync();//完成关闭客户端流
- }
- catch (Exception ex)
- {
-
- }
- }
- }
- }
方法二:一次性传输
- /// <summary>
- /// 调用gRPC 客户端流式图片上传(一次性传输)
- /// </summary>
- public async void UpLoadImgStream(List<IFormFile> upfile)
- {
- //获取页面传递的文件流
- foreach (var formFile in upfile)
- {
- if (formFile.Length > 0)
- {
- #region 获取gRPC接口
- AppContext.SetSwitch("System.Net.Http.SocketsHttpHandler.Http2UnencryptedSupport", true);
- var channel = GrpcChannel.ForAddress("http://localhost:8099/");
- var client = new UpImgStream.UpImgStreamClient(channel);
- #endregion
-
- //获取文件的后缀名
- string fileExt = formFile.FileName.Substring(formFile.FileName.LastIndexOf('.') + 1); //文件扩展名
-
- Metadata entries = new Metadata();
- entries.Add("fileExt", fileExt);
- AsyncClientStreamingCall<StreamRequest, UpImgStreamReply> call = client.DoUpLoad(entries);//先调用服务后面在提供数据
-
- //得到文件流
- Stream stream = formFile.OpenReadStream();
-
- try
- {
- //方法1:一次传递完
- StreamRequest streamRequest = new StreamRequest() { Content = ByteString.FromStream(stream) };
- await call.RequestStream.WriteAsync(streamRequest);
-
- await call.RequestStream.CompleteAsync();//完成关闭客户端流
- }
- catch (Exception ex)
- {
-
- }
- }
- }
- }
得到流式调用的返回值:
- await call.RequestStream.CompleteAsync();//完成关闭客户端流(注意一定要调用不然整个调用过程完成不了)
- //得到返回值
- UpImgStreamReply upImgStreamReply = await call.ResponseAsync;
下载地址:http://www.tnblog.net/resource/show/aojiancc2/af3134fbbe174025ad34e7ccf7de465f
欢迎加群讨论技术,1群:677373950(满了,可以加,但通过不了),2群:656732739。有需要软件开发,或者学习软件技术的朋友可以和我联系~(Q:815170684)
评价