API无法返回SSH下载的音频文件问题求助
问题分析与解决方案
核心问题原因
静态SftpClient引发并发冲突
代码中使用static修饰的s_sftpClient是全局共享变量,多个请求同时调用时会互相干扰:比如一个请求执行Disconnect()会直接中断其他请求的下载操作,导致返回的MemoryStream内容不完整或为空。APM异步模式的错误使用
采用BeginDownloadFile+轮询等待的方式不可靠,轮询逻辑可能存在漏洞,导致下载未完全完成就调用EndDownloadFile,最终流数据不完整。测试代码中流位置未重置
测试代码执行callReport.CopyTo(file)后,流的Position已移动到末尾,直接return File时ASP.NET无法读取任何内容,这也验证了流位置对返回结果的影响(原代码中虽设置了Position=0,但其他问题导致流本身无效)。
修复后的代码
1. 修复SSH服务下载方法
public class SshServices { public async Task<MemoryStream> DownloadCallVoiceFile(string uniqueId, CancellationToken cancellationToken) { // 每个请求创建独立的SftpClient实例,用using自动释放资源 using var sftpClient = new SftpClient("host", "user", "password"); await sftpClient.ConnectAsync(cancellationToken); if (!sftpClient.IsConnected) { throw new InvalidOperationException("无法连接到SFTP服务器"); } var serverAddress = @"\file\monitor\saved\Voice.Wav"; var stream = new MemoryStream(); // 使用原生异步方法替代APM模式,确保下载完全完成 await sftpClient.DownloadFileAsync(serverAddress, stream, cancellationToken); sftpClient.Disconnect(); // 重置流位置到起始处,确保ASP.NET能完整读取 stream.Position = 0; return stream; } }
2. 修复Controller方法
public virtual async Task<ActionResult> DownloadCallVoiceFile(string uniqueId, CancellationToken cancellationToken) { var callReport = await _callCenterService.DownloadCallVoiceFile(uniqueId, cancellationToken); return File(callReport, "audio/wav", "1.wav"); }
3. 修正测试代码(可选)
如果需要保留本地保存测试,需在复制后重置流位置:
public virtual async Task<ActionResult> DownloadCallVoiceFile(string uniqueId, CancellationToken cancellationToken) { var callReport = await _callCenterService.DownloadCallVoiceFile(uniqueId, cancellationToken); using (FileStream file = new FileStream(@"C:\Users\Ya\Desktop\TestFile.wav", FileMode.Create, FileAccess.Write)) callReport.CopyTo(file); // 重置流位置到起始处 callReport.Position = 0; return File(callReport, "audio/wav", "1.wav"); }
修复说明
- 移除
static修饰的SftpClient,每个请求使用独立实例,彻底避免并发请求间的资源冲突。 - 改用
DownloadFileAsync原生异步方法,依托async/await确保下载操作完全完成后再执行后续逻辑,消除轮询带来的不确定性。 - 使用
using语句自动释放SftpClient资源,避免连接泄漏。
内容的提问来源于stack exchange,提问作者Yasim Yasin
相关产品推荐
相关产品推荐

