【发布时间】:2022-01-26 21:11:17
【问题描述】:
这几天我都想不通。我已经尝试了一切。我必须更改我的云存储,所以我正在尝试重构。首先,我在中间类中使用 MinIO 来连接存储。
S3ObjectStorage.cs
public class S3ObjectStorage
{
private MinioClient _client;
private string _bucketName;
public S3ObjectStorage(string key, string secret, string region, string httpsEndPoint, string bucketName) {
_client = new MinioClient(httpsEndPoint, key, secret, region).WithSSL();
_bucketName = bucketName;
}
public async Task<string> ListFilesAsync(string path)
{
return await ListObjects(path, false);
}
private async Task<string> ListObjects(string path, bool isDir) {
var files = await _client.ListObjectsAsync(_bucketName, path)
.Where<Item>(f => (isDir) ? (f.Key.EndsWith("/") && f.IsDir) : !f.Key.EndsWith("/"))
.ToList();
return Newtonsoft.Json.JsonConvert.SerializeObject(files);
}
}
TestPage.aspx.vb(运行正常)
Public Class TestPage
Inherits Page
Protected Async Sub Page_Load(sender As Object, e As EventArgs) Handles Me.Load
cs = New S3ObjectStorage(CS_KEY, CS_SECRET, CS_REGION, HTTPS_ENDPOINT, BUCKET_NAME)
End Sub
Private Async Function List(path As String) As Task
Dim resultFiles As String = Await cs.ListFilesAsync(path)
Dim files = Newtonsoft.Json.JsonConvert.DeserializeObject(resultFiles)
Me.rptFiles.DataSource = files
Me.rptFiles.DataBind()
End Function
End Class
稍后我会尝试使用另一种技术,但现在,我需要在 ASMX 中使用 web 方法来尽可能少地修改代码。使用其他云存储,所有方法都是同步的,但 MinIO 没有。
index.aspx
<script type="text/javascript" language="javascript">
function listFiles() {
$.ajax({
type: 'POST', contentType: "application/json; charset=utf-8", dataType: 'json', async: true,
url: '/WS/WSFileManager.asmx/ListFiles',
...);
WSFileManager.asmx.vb(尝试两种方式)
<WebMethod(EnableSession:=True)>
<ScriptMethod(ResponseFormat:=ResponseFormat.Json)>
Public Async Function ListFiles(signature As String, requestCode As String, previousDeleted As String) As Threading.Tasks.Task(Of String)
'First way
Dim minioClient As New MinioClient(GlobalConstants.S3_HTTPS_ENDPOINT,
GlobalConstants.S3_KEY,
GlobalConstants.S3_KEY,
GlobalConstants.S3_REGION)
minioClient.WithSSL()
Dim files As New List(Of DataModel.Item)
Dim observable As IObservable(Of DataModel.Item) = minioClient.ListObjectsAsync(GlobalConstants.S3_BUCKET_NAME, pathApp, False)
Dim suscription As IDisposable = observable.Subscribe(
Sub(item)
files.Add(item)
End Sub)
suscription.Dispose()
'files.Count always is 0
'Second way
Dim s3Storage As New S3ObjectStorage(GlobalConstants.S3_KEY, GlobalConstants.S3_SECRET,
GlobalConstants.S3_REGION, GlobalConstants.S3_HTTPS_ENDPOINT,
GlobalConstants.S3_BUCKET_NAME)
Dim resultFiles As String = Await s3Storage.ListFilesAsync(pathApp)
'**Never reach this line**
....
我当前的云存储将于明年 1 月 31 日结束,因此我需要尽快运行新的云存储。
非常感谢!
【问题讨论】:
-
在您的情况下超时可能意味着连接从未完成。首先,我会检查服务器上的事件查看器,看看是否有任何与您的应用程序相关的错误消息。然后我会使用像wireshark这样的嗅探器来比较工作和非工作连接。您正在使用 TLS,因此请确保在嗅探器中使用的是 TLS 1.2 或 TLS 1.3。其他版本的 TLS 已过时。使用 TLS,服务器发送一个证书块(可以通过嗅探器查看),其中包含可用于加密的证书名称,然后客户端在存储中查找证书名称。
-
谢谢。但是,当我从 TestPage 调用 ListFilesAsync 时,它几乎立即返回结果。同样的 ASMX,使用另一个云,从不返回超时。
Dim resDC As GetDirectoryContentResponse = cs.GetDirectoryContent(CSAccessKeyId, ZuluTime, GenerateAppStorageSignature("GetDirectoryContent", ZuluTime), pathApp, "", "", "", "File") If resDC.Error IsNot Nothing Then Return $"{{""error"":""Error listing files.<br />{resDC.Error.ErrorCode } {resDC.Error.Description}""}}" End If -
其他云总是有效吗?你说永远不会返回超时。不知道这意味着什么。这是否意味着永远不会失败或仅在失败时不返回错误。当连接失败时,有时您会收到错误消息,有时它会静默失败。
-
我的意思是我之前遇到过错误,但我永远不会在使用相同的 ASMX 的其他云上遇到超时。我只是更改了对方法的调用并在函数定义中添加了“异步”。
-
异步方法必须获取 EOM(消息结束或等效项)才能知道何时收到所有数据。连接必须在您得到响应之前完成。未完成的连接永远不会得到响应。因此,在一种情况下,您的连接正在完成并返回响应。在其他情况下,您的连接未完成,这就是我在上一条消息中所说的。所以看起来你的连接没有完成,异步正在等待 EOM。
标签: c# vb.net async-await asmx webmethod