El proceso de conexión de Unity a AWS S3, AWS SDK para registros de errores de Unity

AWS S3, el servicio de servidor de recursos de Amazon, ha estado estudiando este contenido recientemente. Registre el contenido de las trampas.

Después de estudiar las dos partes de AWS SDK para unity y AWS SDK para .net
, es difícil conectarse a unity, la razón principal es que no existe una API oficial y la versión de unity se usa en función del uso de .net. versión.


El nombre de API de AWS SDK es similar independientemente de la plataforma y se divide principalmente en 3 series.

  1. Consulta de lista
  2. Obtener Obtener, descargar
  3. poner subir

Interfaces principales:

inicialización

Cliente AmazonS3

m_AWSClient = new AmazonS3Client(strAccessKey, strSecretKey, regionEndpoint)

Es necesario pasar AccessKey, SecretKey y EndPoint durante la construcción.

Operaciones de objetos

ObtenerObjeto
PonerObjeto

Hubo un problema en Unity.
GetObject no pudo obtener el progreso de la descarga, por lo que esta API se abandonó y se usó UnityWebRequest para la descarga. Luego ocurrieron un montón de excepciones. Aquí hay dos puntos clave:

AWSConfigs.HttpClient = AWSConfigs.HttpClientOption.UnityWebRequest;
public CertificateHandlerPublicKey Certificate { get; private set; } = new CertificateHandlerPublicKey();

public class CertificateHandlerPublicKey : CertificateHandler
{
    protected override bool ValidateCertificate(byte[] certificateData)
    {
        return true;
    }
}

uwq = UnityWebRequest.Get(strURL);
uwq.certificateHandler = AWSProxy.Instance.Certificate;

Después de configurarlo, será normal.

PutObject, sube un archivo. Normalmente, haríamos esta operación de carga en un modo que no sea tiempo de ejecución en el Editor, pero sucedió algo muy extraño en AWS: el objeto principal AmazonS3Client informó un error, diciendo que no estaba inicializado. Es necesario llamar a AmazonS3Client antes de crear una nueva

UnityInitializer.AttachToGameObject(this.gameObject);

Me sorprendí al instante. Esta es una API en tiempo de ejecución, lo que significa que la carga debe realizarse mientras Unity se está ejecutando. Después de las pruebas, descubrí que sí es posible.

operación de permiso

GetACL
PutACL
Get no tiene ningún problema. Probé Put bajo unity e informé un error de WebRequestHeader. Emm... según la experiencia, la solicitud carece de información de encabezado, así que simplemente complete la información de encabezado. Sin embargo, AWS SDK El dll está empaquetado. Esto es embarazoso. No es necesario interceptar el paquete y luego enviarlo.
Así que probé la versión .net nuevamente, no hubo ningún problema y pude usarla normalmente. Esto es increíble. Pero funciona.

Obtener lista

ListObjects
encontró un problema al obtener la lista. AWS SDK solicitó contenido en una determinada ruta y devolvió hasta 1000 archivos de información. Los más desaparecerían. La depuración encontró que hay un campo NextMarker en la estructura devuelta ListObjectsResponse .
También hay un marcador de campo en ListObjectsRequest. Intenté pasar la marca devuelta por primera vez a la siguiente solicitud y fue exitoso. Por lo tanto, AWS devuelve la información de la lista según la lógica de paginación, con un límite superior de 1000. Tiene sentido si lo piensa detenidamente: por motivos de rendimiento y ancho de banda de transmisión, para evitar que el tamaño del archivo sea demasiado grande, se adopta la paginación.

		public void GetList(string strUrlPre, out bool isSuc, out Dictionary<string, long> result)
		{
			isSuc = true;
			result = new Dictionary<string, long>();

			Debug.Log("AWSApi Connect,Start GetList");

			string strMark = null;
			while (true)
			{
				ListObjectsRequest request = new ListObjectsRequest();
				request.BucketName = m_strBucket;
				request.Prefix = strUrlPre;
				request.Marker = strMark;
				try
				{
					ListObjectsResponse response = m_AWSClient.ListObjects(request);
					var listServer = response.S3Objects;
					for (int i = 0; i < listServer.Count; i++)
					{
						result.Add(listServer[i].Key, listServer[i].Size);
					}
					strMark = response.NextMarker;
					if (string.IsNullOrEmpty(strMark))
					{
						break;
					}
				}
				catch (System.Exception e)
				{
					isSuc = false;
					Debug.LogError("AWSApi Connect, Error : " + e.Message);
					break;
				}
			}
		}

Encontré un problema al descargar un texto de AWS S3.
Descargué el texto y obtuve la información del texto a través de UnityWebRequest y descubrí que el contenido de la cadena era diferente del contenido cargado.

var task = UnityWebRequest.Get(strNetPath);
string strResult = task.downloadHandler.text;

Una vez completada la descarga, se obtiene task.downloadHandler.text,
depure y vea el contenido, que es el mismo que el contenido de texto que utilicé al cargar. Pero la lógica posterior no logró analizar el contenido del texto.
Después de la depuración, el contenido de la cadena era el mismo, así que usé string.toChatArray() para verificar la diferencia entre cada carácter. Descubrí que las cadenas se veían iguales, pero el primer carácter era un carácter vacío. String.trim era no válido para este carácter vacío debido a esto. El carácter vacío y el segundo carácter forman la primera palabra de cadena.

byte[] bytes = task.downloadHandler.data;

También es incorrecto obtener bytes, hay un contenido vacío al principio.

Baidu obtuvo una explicación para este problema: https://blog.csdn.net/shersfy/article/details/54614720
Es razonable... agregue el código.

string strResult = task.downloadHandler.text;
if (strResult[0] == 65279)
{
    strResult = strResult.Substring(1);
}
callBack?.Invoke(true, strResult);

Luego está la cuestión del uso de herramientas de producción .net.

La descripción de .net en la documentación oficial es que se puede buscar la extensión en Visual Studio para AWS y se puede encontrar el complemento.
Fingí y descubrí que no servía de nada, me veía confundido y no lo expliqué en absoluto.

Así que descargué manualmente el .net dll.
Es válido a partir del 3 de septiembre de 2021. https://sdk-for-net.amazonwebservices.com/latest/v3/aws-sdk-net45.zip.
Si no es válido, Luego vaya al sitio web oficial. Busqué SDK para .net en el cuadro de búsqueda del sitio web, pero fue realmente problemático encontrarlo.
Después de descomprimir el dll interno, agregue una referencia y use una herramienta en Windows para sacarlo.

Porque generalmente los contratos se emiten en plataformas duales, ios y android. Android se puede distribuir en Windows. El empaquetado de iOS debe estar en una máquina Mac.
Entonces lo probé y ejecuté .net en Mac.
El método más sencillo es una máquina virtual.

Mi modelo es un chip M1 , Dios mío. A partir del 1 de septiembre de 2021, solo el escritorio paralelo puede admitir máquinas virtuales de Windows en el chip M1. Después de instalar el sistema, instale .net. Ejecutar... bien, no hay respuesta

Entonces la solución fue reemplazada, porque .net se puede ejecutar directamente en Mac, y Baidu puede hacerlo.
donet puede iniciar directamente la aplicación de consola web central .net.
Probé hola mundo y funcionó normalmente sin ningún problema.

Continúe probando las interfaces relevantes de AWS SDK para .net, pero falla. El mensaje de error es que AWSConfig está realizando una operación de archivo local y no puede encontrar la ruta.
Más, demasiado vago para hacerlo, declarado fracaso .

Por lo tanto, todavía usamos SVN para sincronizar el contenido que debe cargarse en la intranet y operarlo en una máquina con Windows.


Luego está el empaquetado: no hay problema en empaquetar el APK, pero al ejecutarlo
, encontrará que AmazonS3Client arrojará una excepción MissingMethodException cuando sea nuevo.
AWS SDK para Unity contiene muchos archivos DLL después de la importación, y el archivo so no tiene nada que ver con la información de registro.
Entonces el problema proviene del dll. Si verifica el dll, encontrará que
Insertar descripción de la imagen aquí
el Targets .net 3.5 final
es .net2.0 por defecto en unity2019. Luego cámbielo y aumente la versión .net de Unity.
Luego descubrí que el error MissingMethodException todavía ocurre.
Piénselo, cuando se ejecuta, no se puede encontrar el código, pero está bien en la PC, entonces el código puede cortarlo y luego agregar el enlace. (Código de unidad link.xml En relación con el corte, puedes ir a Baidu)

<?xml version="1.0" encoding="utf-8"?>
<linker>
  <assembly fullname="AWSSDK.CognitoIdentity" preserve="all" />
  <assembly fullname="AWSSDK.Core" preserve="all" />
  <assembly fullname="AWSSDK.S3" preserve="all" />
  <assembly fullname="AWSSDK.SecurityToken" preserve="all" />
</linker>

Continuar, el error persiste y aparece en

AWSConfigs.HttpClient = AWSConfigs.HttpClientOption.UnityWebRequest;

Aparece esta línea de código y todavía es un problema de reducción.

NullReferenceException: Object reference not set to an instance of an object.
      at Amazon.Runtime.Internal.UnityWebRequestWrapper..cctor () [0x00000] in <00000000000000000000000000000000>:0 
      at Amazon.AWSConfigs.set_HttpClient (Amazon.AWSConfigs+HttpClientOption value) 

AWS的内部异常是:
TypeInitializationException

después de un intento

<linker>
  <assembly fullname="UnityEngine">
    <type fullname="UnityEngine.Networking.UnityWebRequest" preserve="all" />
    <type fullname="UnityEngine.Networking.UploadHandlerRaw" preserve="all" />
    <type fullname="UnityEngine.Networking.UploadHandler" preserve="all" />
    <type fullname="UnityEngine.Networking.DownloadHandler" preserve="all" />
    <type fullname="UnityEngine.Networking.DownloadHandlerBuffer" preserve="all" />
  </assembly>
	<assembly fullname="AWSSDK.CognitoIdentity" preserve="all"/>
	<assembly fullname="AWSSDK.Core" />
	<assembly fullname="AWSSDK.S3" />
	<assembly fullname="AWSSDK.SecurityToken" />
</linker>

Woohoo, lo logré.

Luego, durante el proceso de ejecución de la lógica, descubrí un problema
relacionado con List en la API del SDK de AWS, como ListBucketsAsync. Cuando se ejecuta en Android, no habrá devolución de llamada, tiempo de espera ni herencia. Estoy muy confundido. Debido a que no hay una API en el SDK de AWS para demostrar que la conexión se realizó correctamente, la idea de utilizar la información del depósito para probar si la conexión se puede realizar correctamente falló.

Me quejé de nuevo.
Realmente no hay explicación en la API oficial de AWS. No hay documentación oficial de Unity. Solo puedo encontrarla en el foro, pero este tipo de error es difícil de buscar.

Entonces usemos la API de Unity. Solicitud web de Unity.

Seguridad:

AWSProxy.Instance.GenerateDynamicURL

Este intento de API es utilizable y devuelve la URL correctamente.
Principalmente produce una cadena de URL con información cifrada.
Si la cuenta durante la inicialización tiene permisos, la descarga puede realizarse correctamente; de ​​lo contrario, se devolverá un error HTTP.


La programación es infinita.
Todos son bienvenidos a comunicarse. Si hay algo que no está claro o está mal, también pueden chatear conmigo en privado.
Mi QQ 334524067 Dios-como Didi

Supongo que te gusta

Origin blog.csdn.net/qq_37776196/article/details/120034272
Recomendado
Clasificación