我正在开发一个 API,它接收消息并将其以 .json 格式上传到 SFTP 服务器。但是,连接时间太长,SFTP 连接需要 1 秒多,这太多了。 我想知道是否有什么方法可以连接到服务器并发送文件而无需等待这么长时间。
我想过保存文件,回复客户端,然后用这种方法上传文件:
public async Task Upload(string localPath, string remotePath)
{
await Task.Run(() =>
{
// upload code here
});
}
但是,如果上传过程中出现异常,API可能已经向客户端返回OK,无法通知客户端上传失败。
这是我当前用于上传文件的现有代码:
public void Upload(string localPath, string remotePath)
{
try
{
using (var sftp = new SftpClient(...))
{
sftp.Connect(); // Very slow
sftp.UploadFile(...);
sftp.Disconnect();
}
catch (Exception ex)
{
_logger.LogError(ex, "Error Upload SFTPHandler");
}
}
有人可以建议一个解决方案来连接到 SFTP 服务器并发送文件而无需等待这么长时间吗?
最佳答案
您可以存储上传状态,并单独检查是否已上传。例如,您可以将状态缓存在 ConcurrentDictionary
中。然后,客户端可以定期轮询上传状态。
假设您使用的是 SSH.Net 客户端,您还可以使用其异步方法。
static ConcurrentDictionary<string, bool> _statuses = new();
[HttpPost]
public async Task UploadFile(string localPath, string remotePath)
{
_statuses[remotePath] = false;
Task.Run(() => Upload(localPath, remotePath));
}
private async Task Upload(string localPath, string remotePath)
{
try
{
using var sftp = new SftpClient(...);
sftp.ConnectAsync();
await TaskFactory.FromAsync(
(input, path, asyncCallback, state) =>
sftp.BeginUploadFile(input, path, asyncCallback),
sftp.EndUploadFile,
..., // some filestream
remotePath,
null);
_statuses[remotePath] = true;
sftp.Disconnect();
}
catch (Exception ex)
{
_logger.LogError(ex, "Error Upload SFTPHandler");
}
}
[HttpPost]
public async Task<bool> IsUploaded(string remotePath)
{
if (!_statuses.TryGetValue(remotePath, out var value))
{
// IIS was restarted.
// check SFTP for finished upload.
_statuses.Add(someStatus);
}
return value;
}
您可能需要考虑某种在 IIS 服务器重新启动时缓存状态的方法。
关于c# - 有没有异步方式连接到SFTP服务器?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/75745090/