Search Unity

  1. We are migrating the Unity Forums to Unity Discussions. On July 12, the Unity Forums will become read-only.

    Please, do not make any changes to your username or email addresses at id.unity.com during this transition time.

    It's still possible to reply to existing private message conversations during the migration, but any new replies you post will be missing after the main migration is complete. We'll do our best to migrate these messages in a follow-up step.

    On July 15, Unity Discussions will become read-only until July 18, when the new design and the migrated forum contents will go live.


    Read our full announcement for more information and let us know if you have any questions.

Question AWS SDK for WebGL

Discussion in 'Web' started by HelloSpriTe, May 11, 2023.

  1. HelloSpriTe

    HelloSpriTe

    Joined:
    Nov 13, 2019
    Posts:
    5
    Hi!
    I need help
    I use AWS SDK for getting data (addressables, jsons, etc...) files from S3 bucket.

    For example:
    Code (CSharp):
    1.  AmazonS3Client cr = new AmazonS3Client("key1", "key2",
    2.             new AmazonS3Config
    3.             {
    4.                 ServiceURL = "https://" + "myUrl",
    5.                 MaxErrorRetry = 0,
    6.                 Timeout = TimeSpan.FromSeconds(60)
    7.             }
    8.         );
    9. var downloadRequest = new GetObjectRequest
    10. {
    11.     Key = "myFilePath",
    12.     BucketName = "bucketName"
    13. };
    14. var getObjectResponse = await cr.GetObjectAsync(downloadRequest, cts.Token).AsUniTask();
    15.  
    (Of course, I replaced real values to fictional)
    Also, I use UniTask package for async.

    It works perfect for next build platforms: PC, Android, IOS.
    But if I build WebGL, any request to this API return the <TypeInitializationException> like this:

    System.TypeInitializationException: The type initializer for 'Amazon.Util.Internal.RegionFinder' threw an exception. ---> System.ArgumentNullException: Value cannot be null.
    Parameter name: stream
    at System.IO.StreamReader..ctor (System.IO.Stream stream, System.Text.Encoding encoding, System.Boolean detectEncodingFromByteOrderMarks, System.Int32 bufferSize, System.Boolean leaveOpen) [0x00000] in <00000000000000000000000000000000>:0



    I used all the advice I found on the Internet:
    - Added a link.xml file indicating AWS
    - Corrected versions of AWS and its dependencies (microsoft.bcl.asyncInterfaces, etc...)
    - Changed types of compression and decompression
    - Tried to combine different versions of libraries, etc.

    Anyway, it not worked and throw TypeInitializationException.

    How it can be fixed? Or AWS SDK not worked in WebGL platform? (I used OpenServer for running project)
    Thank you in advance
     
  2. manuelgoellnitz

    manuelgoellnitz

    Joined:
    Feb 15, 2017
    Posts:
    398
  3. HelloSpriTe

    HelloSpriTe

    Joined:
    Nov 13, 2019
    Posts:
    5
    Yes, unfortunately, AWS SDK really not supported in WebGL.
    They write supported platforms - standalone, android and ios.
    I finded this here: https://github.com/aws/aws-sdk-unity-net
    Anyway, i rewrote code to standard UnityWebRequests.
    Thank you for answer.
     
  4. manuelgoellnitz

    manuelgoellnitz

    Joined:
    Feb 15, 2017
    Posts:
    398
    Can you give more details about your solution?
     
  5. HelloSpriTe

    HelloSpriTe

    Joined:
    Nov 13, 2019
    Posts:
    5
    Certainly.
    My application is on the server, and I thought to contact the S3 server every time to get the necessary data.
    But since it is impossible to do this from WebGL, I pre-determine all files, addressables, etc. to a local folder on the server, and using UnityWebRequest for get data from this folder.
    And my colleague - a web developer - just wrote a script that, when data changes on the S3 server, automatically also synchronizes this data with the data folder on the server.

    Here is an example script for getting data from a json file:
    Code (CSharp):
    1.  public static async UniTask<string> LoadTextFromServerFile(string filePath) //path example: //service/dictionaries/config.json
    2.         {
    3.             using var webRequest = UnityWebRequest.Get(filePath);
    4.  
    5.             await webRequest.SendWebRequest().ToUniTask();
    6.  
    7.             var pages = filePath.Split('/');
    8.             var page = pages.Length - 1;
    9.             var result = "Empty";
    10.            
    11.             switch (webRequest.result)
    12.             {
    13.                 case UnityWebRequest.Result.ConnectionError:
    14.                 case UnityWebRequest.Result.DataProcessingError:                  
    15.                 case UnityWebRequest.Result.ProtocolError:
    16.                     Debug.LogError(pages[page] + " - Error: " + webRequest.error);
    17.                     break;
    18.                 case UnityWebRequest.Result.Success:
    19.                     Debug.Log(pages[page] + " - Received successfully");
    20.  
    21.                     result = webRequest.downloadHandler.text;
    22.                     break;
    23.             }
    24.             return result;
    25.         }
    And for loading addressables from localPath:

    Code (CSharp):
    1. public async UniTask LoadAddressables(string catalogPath, CancellationToken cancellationToken = default)
    2.     {
    3.         Addressables.ClearResourceLocators();
    4.  
    5.         await Addressables.LoadContentCatalogAsync(catalogPath).ToUniTask(cancellationToken: cancellationToken);    
    6.  
    7.         await UpdateCatalogs().ToUniTask(this);
    8.     }
    UpdateCatalogs - just use 2 methods from Addressable package

    Addressables.CheckForCatalogUpdates();
    Addressables.UpdateCatalogs(catalogsToUpdate);
     
    GDevTeam likes this.
  6. manuelgoellnitz

    manuelgoellnitz

    Joined:
    Feb 15, 2017
    Posts:
    398
    Ah I see, I thought your solution was to talk with the AWS service via REST api or something
     
  7. HelloSpriTe

    HelloSpriTe

    Joined:
    Nov 13, 2019
    Posts:
    5
    I tried to do this, but the S3 server does not support such requests, it seems
    Anyway, I didn't manage to do it this way.
     
  8. socialtrens

    socialtrens

    Joined:
    Oct 23, 2017
    Posts:
    65
    S3 support REST api. I'm currently using addressable with S3.
    Source: https://docs.aws.amazon.com/AmazonS3/latest/API/Welcome.html

    Use
    Code (CSharp):
    1. Addressables.WebRequestOverride = WebRequestOverride;
    In WebRequestOverride, input your s3 credential and compute it using ComputeSigner. Then, add the results into UnityWebRequest headers.
     
  9. tsabbir96

    tsabbir96

    Joined:
    Jun 18, 2023
    Posts:
    1

    Hi @HelloSpriTe , It looks like an excellent solution for WebGL users. I am also facing the same problem and would like to utilize your solution. But my problem is no matter what UnityWebRequest does not find my LocalFilePath. I am not sure what I am doing wrong. Could you provide some idea?
     
  10. HelloSpriTe

    HelloSpriTe

    Joined:
    Nov 13, 2019
    Posts:
    5
    Hello!

    Perhaps you specified the paths incorrectly in the addressable settings?
    There you need to first configure the profile, and then in each group of your addressables you select exactly this profile and the type of path (local or remote), and it will display the appropriate paths. If you send screenshots of your settings, I could compare them with mine.
     
  11. SebastianBlandon

    SebastianBlandon

    Joined:
    Jun 20, 2023
    Posts:
    1
    @manuelgoellnitz Can you provide me with an example of your solution? Did you call the AWSSDK library in your .jslib? or how did you implemented browser scripting?
     
  12. manuelgoellnitz

    manuelgoellnitz

    Joined:
    Feb 15, 2017
    Posts:
    398
    I made a javascript file with all the communication with AWS and the jslib for the communication with unity. This way I did not need to create a new build when there was an error in the communication with AWS.