0

I can't figure this out in days. I have tried everything. I have to change my cloud storage so I'm trying to refactor. First of all, I'm using MinIO in an intermediate class to connect the storage.

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 (runs properly)

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

Later I will try to use another technology, but for now, I need to use a webmethod in an ASMX to modify the code as little as possible. With the other cloud storage, all methods were synchronous, but MinIO doesn't.

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 (trying 2 ways)

    <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**
....

My current cloud storage ends next January 31st, so I need the new one runs as soon as possible.

Thank you very much!

6
  • Timeout in your case probably means the connection never completed. First I would check the Event Viewer on the server to see if there are any error messages associated with your application. Then I would use a sniffer like wireshark to compare the working and non working connection. You are using TLS so make sure in the sniffer that TLS 1.2 or TLS 1.3 is being used. Other versions of TLS are obsolete. With TLS the server sends a certificate block (can see with sniffer) with names of certificate that can be used for encryption and then client looks up in stores the names of the certificates. Commented Jan 25, 2022 at 10:14
  • Thanks. However, when I call ListFilesAsync from TestPage it returns a result almost immediately. And the same ASMX, using the other cloud, nevers returns a timeout. 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 Commented Jan 25, 2022 at 10:25
  • Does the other cloud always work? You said never returns timeout. Not sure what this means. Does it mean never fails or just when it fails no error is returned. When a connection fails sometimes you will get an error and sometimes it fails silently. Commented Jan 25, 2022 at 10:53
  • I mean I've get errors before but I'd never get a timeout with the other cloud using this same ASMX. I just changed the call to method and added "async" in function definition. Commented Jan 25, 2022 at 11:07
  • An Async method must get a EOM (end of message or equivalent) to know when all the data is received. A connection must complete before you get a response. A connection that doesn't complete never gets a response. So in one case your connection is completing and returning a response. You other case your connection is not completing which is what I said in my previous message. So it looks like you connection is not completing and the Async is waiting for an EOM. Commented Jan 25, 2022 at 11:22

1 Answer 1

0

It was very very simple!

I have returned to putting the method in ASMX as synchronous

WSFileManager.asmx.vb

<WebMethod(EnableSession:=True)>
<ScriptMethod(ResponseFormat:=ResponseFormat.Json)>
Public Function ListFiles(signature As String, requestCode As String, previousDeleted As String) As String

    Dim task = Threading.Tasks.Task.Run(Async Function() Await s3Storage.ListFiles(pathApp))
    task.Wait()
    Dim lFiles = Newtonsoft.Json.JsonConvert.DeserializeObject(Of List(Of DataModel.Item))(task.Result)
...
End Function

And in frontend, I've taken the opportunity to also stop using jQuery index.aspx

<script type="text/javascript" language="javascript">
function listFiles() {
    const fetchOptions = {
        method: 'POST', headers: {'Content-Type': 'application/json; charset=utf-8'},
        body: JSON.stringify({ /* parameters */ })
    };
    const result = fetch('/WS/WSFileManager.asmx/ListFiles', fetchOptions)
        .then(response => response.json())
        .catch(error => console.error('Error:', error))
        .then(data => console.log(JSON.parse(data.d).legth+' files')));
...
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.