Dart编写的gRPC客户端流结束后服务端阻塞问题求助
问题:gRPC流式上传图片时服务端无法退出
await for循环 问题背景
我希望通过gRPC将图片从客户端上传至服务端,编写了相关proto文件、客户端和服务端代码,图片已成功发送至服务端(可通过打印确认),但服务端始终无法退出await for循环,客户端一段时间后触发超时错误。
相关代码
Proto文件
syntax = "proto3"; service EshopService { rpc UploadImage (stream ImageToUpload) returns (ImageLink); } message ImageToUpload { bytes image = 1; } message ImageLink { string image_links = 1; }
客户端代码
Future<ImageLink> uploadImage(ImageToUpload image) async { return await stub.uploadImage(streamImage(images.image)); } Stream<ImageToUpload> streamImage(List<int> image) async* { for (var element in image) { yield ImageToUpload(image: [element]); } }
服务端代码
Future<ImageLink> uploadImage(grpc.ServiceCall call, Stream<ImageToUpload> request) async { print('uploading'); final List<int> image = []; await for (var bytes in request) { image.addAll(bytes.image); } print('image gotten'); File imageFile = File('image.jpg'); await imageFile.writeAsBytes(image); return ImageLinks(imageLinks: 'image'); }
错误信息
gRPC Error (code: 4, codeName: DEADLINE_EXCEEDED, message: Deadline exceeded, details: null, rawResponse: null, trailers: {})
问题原因与解决方法
核心问题
- 服务端存在类型错误:返回的
ImageLinks与proto定义的ImageLink不匹配,导致服务端无法正确生成响应,客户端一直等待最终超时。 - 客户端流发送逻辑不合理:逐个字节拆分发送消息,不仅效率极低,还可能导致gRPC无法正确识别流结束信号。
修复步骤
修正服务端返回类型
将服务端的返回语句改为与proto定义一致的类型:return ImageLink(imageLinks: 'image');优化客户端流发送逻辑
改为按固定大小分块发送图片字节,既提升效率,又能让gRPC正确识别流结束:Stream<ImageToUpload> streamImage(List<int> image) async* { const chunkSize = 1024; // 按1KB分块 for (int i = 0; i < image.length; i += chunkSize) { int end = i + chunkSize; if (end > image.length) end = image.length; yield ImageToUpload(image: image.sublist(i, end)); } // async*函数执行完毕后,流会自动关闭并发送结束信号 }设置合理的超时时间
客户端调用时可手动设置合适的超时,避免因网络或处理耗时触发不必要的超时:Future<ImageLink> uploadImage(List<int> imageBytes) async { final callOptions = CallOptions(timeout: Duration(seconds: 30)); return await stub.uploadImage(streamImage(imageBytes), options: callOptions); }
验证逻辑
修复后,客户端流发送完毕时,gRPC会自动向服务端发送流结束信号,服务端的await for循环会正常退出,完成图片写入后返回正确的响应,客户端不会再触发超时错误。
内容的提问来源于stack exchange,提问作者Kimiya Zargari
相关产品推荐
相关产品推荐

