AWS S3,亚马逊的资源服务器服务,最近在研究这一块内容。记录一下踩坑的内容。

研究了AWS SDK for unity和AWS SDK for .net 两部分
unity很难接,主要原因是官方没有api,完全是参考.net版本的使用来用unity版本的。


AWS SDK的API命名不管啥平台都差不多,主要分3个系列

  1. List 查询
  2. Get 获取,下载
  3. Put 上传

主要的接口:

初始化

AmazonS3Client

m_AWSClient = new AmazonS3Client(strAccessKey, strSecretKey, regionEndpoint)

构造时候需要传入AccessKey,SecretKey,EndPoint

对象操作

GetObject
PutObject

Unity下出现了问题
GetObject是没办法获取下载进度的,所以弃用了这个Api,改用了UnityWebRequest进行下载,然后就出了一堆异常了,这边记两个关键点:

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;

设置完之后就正常了。

PutObject,上传一个文件。通常上传这个操作我们会做在Editor下非Runtime的,但是AWS就出现了一个很奇怪的事情,主对象AmazonS3Client出现了一个报错,说没有初始化。AmazonS3Client在new之前,需要调用

UnityInitializer.AttachToGameObject(this.gameObject);

瞬间就惊呆了,这是个Runtime的API,也就是说上传需要在Unity运行时。测试后发现,的确是可以的。

权限操作

GetACL
PutACL
Get没啥问题,Put在unity下尝试了,结果报了一个WebRequestHeader的错误,emm…按照经验来说请求缺少了头信息,那补全header信息就好了,但是AWS的SDK把内容全封装dll了。这就尴尬了。总不见得截包,再传出去。
于是与又尝试了.net版本,完全没问题,可以正常用。这就很神奇了。不过能用就行。

获取列表

ListObjects
在获取列表时候,遇到了个问题,aws sdk请求某个路径下内容,最多返回1000个文件信息,再多就没有了。调试发现返回的结构ListObjectsResponse 里,有个字段 NextMarker
在ListObjectsRequest里面也有个字段Marker。尝试了一下把第一次返回的mark传给下一次请求,可以获取成功。所以AWS是按照分页的逻辑返回的列表信息,上限1000。仔细一想也很合理,出于性能和传输带宽考虑,为了避免文件量太大,采用分页的方式。

     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;}}}

下载AWS S3上一个文本时候遇到了一个问题
通过UnityWebRequest下载文本和取得text信息,发现string内容和上传的内容不同。

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

下载完成后得到 task.downloadHandler.text;
调试看内容,和我上传时候用的文本内容一样。但是之后的逻辑里对文本内容解析失败了。
调试看string内容也是一样的,于是拿string.toChatArray()去查每一个字符有啥区别,发现了字符串看上去一样,但是首位字符是个空char,string.trim对这个空char无效,因为这个空char和第二位char组成了第一个string字。

byte[] bytes = task.downloadHandler.data;

获取bytes也是不对的,多了开头的空内容。

百度这个问题得到了一个解释:https://blog.csdn.net/shersfy/article/details/54614720
算是合理吧…加入代码。

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

然后就是用.net制作工具问题了

官方文档里面对.net的描述是在visual studio里的扩展可以搜索aws,可以找到插件。
我装了发现没啥用,一脸懵,完全没有说明。

于是手动下载了.net的dll
截止2021年9月3日有效,https://sdk-for-net.amazonwebservices.com/latest/v3/aws-sdk-net45.zip
如果无效了,那就上官方网站的搜索框里面搜sdk for .net找找了,找起来实在是麻烦。
解压后里面的dll,加入引用,windows下撸了一发工具出来。

因为一般发包都是双平台,ios和android。android在windows下发就可以了。ios打包必定在mac机器上。
所以尝试了一下,在mac上面跑.net。
最直接的方法是虚拟机。

我的机型是M1芯片,oh my god,截止2021 9 1日只有parallels desktop可以在M1芯片上支持windows虚拟机,装完系统,装好.net。运行… 很好没有反应

于是替换了方案,因为mac下可以直接运行.net了,这个可以自行百度。
donet可以直接拉起 .net core web的控制台应用。
尝试了hellow world,可以正常运行没有问题。

继续尝试AWS SDK for .net 的相关接口,失败了。报错内容是AWSConfig在进行一个本地的file操作,找不到路径。
over,懒得搞,宣布失败

所以还是用SVN在内网同步需要上传的内容,在windows机器上操作把。


然后是打包,打包APK没有问题,但是运行起来会发现
AmazonS3Client在new的时候,会抛出异常MissingMethodException。
AWS SDK for Unity,导入后里面有好多dll,so文件里和log信息没啥关系。
所以问题出来dll上,查看dll会发现

最后Targets .net 3.5
unity2019默认是 .net2.0,那就改呗,把Unity的.net版本提高。
然后发现,还是会出现错误MissingMethodException.
想一想,运行时,代码找不到,但是在PC上是好的,那有可能是被代码裁减了,那么就加上link.(link.xml unity代码裁减相关,可以百度到)

<?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>

继续,依旧出现报错,出现在

AWSConfigs.HttpClient = AWSConfigs.HttpClientOption.UnityWebRequest;

这一行代码里面出现了,依旧是裁减问题

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

经过一顿尝试

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

呜呼,跑通了。

然后在跑逻辑过程中,发现了问题
AWS SDK的API中的List相关,例如ListBucketsAsync,在Android下跑的时候,不会有任何CallBack,也没有超时,也没有遗产,很纳闷。因为AWS SDK里没有证明连接成功的API,所以想用桶子信息尝试是否可以连接成功,这个想法是失败了。

再次吐槽
查看AWS官方的API实在没啥说明,官方也没有unity的文档,只能进论坛找,但是这种错误很难搜索到。

所以还是用Unity的API吧。UnityWebRequest。

安全性方面:

AWSProxy.Instance.GenerateDynamicURL

这个API尝试是可以用的,可以正确返回URL。
主要是产出一串带有加密信息的URL。
初始化时候的账号有权限,就可以成功下载,不然会返回HTTP错误。


程序学无止尽。
欢迎大家沟通,有啥不明确的,或者不对的,也可以和我私聊
我的QQ 334524067 神一般的狄狄

Unity接入AWS S3过程,AWS SDK for Unity 踩坑记录相关推荐

  1. uniapp unipush接入个推消息推送(各种踩坑记录)安卓+IOS+在线消息+离线消息

    uniapp 消息推送功能实现 上周公司要求做一个消息推送的功能,由于现有的电商APP是用uniapp做的,所以优先考虑uniapp自带的unipush消息推送. ios证书导出踩坑 ios推送证书导 ...

  2. i.MX6ULL裸机篇(二)NXP官方SDK移植之踩坑 网口驱动

    MX6ULL官方SDK移植之踩坑 网口驱动 一.引言 NXP MX6ULL 网口移植其实主要修改底层驱动程序,LWIP协议通用,一般不用修改,这里主要和大家分享在Linux环境下移植修改网口驱动程序. ...

  3. 为Jupyter notebook配置R kernel过程及踩坑记录

    为Jupyter notebook配置R kernel过程及踩坑记录 注意:本文为作者安装过程及折腾的过程,内容比较冗杂,如果读者想直接创建一个属于自己的子环境则参考: 如下文章: anaconda下 ...

  4. Python打包工具Pyintealler打包py文件为windows exe文件过程及踩坑记录+实战例子

    Python打包工具Pyintealler打包py文件为windows exe文件过程及踩坑记录+实战例子 目录 Python打包工具Pyintealler打包py文件为windows exe文件过程 ...

  5. Unity AssetBundle 踩坑记录

    Unity AssetBundle 踩坑记录 editor 下选择什么平台的 ab 加载 Material doesn't have a color property '_Color' UnityEd ...

  6. gitea 手动编译过程,以及踩坑记录

    gitea 手动编译过程,以及踩坑记录 一: 环境介绍 二:下载源码 三:编译安装go 环境 3.1 修改源为阿里 3.2 添加执行权限 3.2 添加环境变量 四:安装nodejs 4.1 添加源 4 ...

  7. DJI Windows SDK踩坑记录

    DJI Windows SDK踩坑记录 前言 DJI Windows SDK现状 DJI官方称WSDK将不会再进行更新维护 DJI Windows SDK无法直接控制Mavic 2 pro的飞行姿态 ...

  8. Unity GPU Instance踩坑记录

    Unity GPU Instance踩坑记录 Unity中GPUInstance主要有两种:一种是unity自动进行的,或者调用Graphics.DrawMeshInstancedIndirect等A ...

  9. Unity个人开发中的踩坑记录(混沌式更新)

    DateTime时间戳计算 一言蔽之,通常使用DateTime计算时间戳,起始时间点为UTC时间1970年1月1日0点整,需手动设置一个基准DateTime来处理. DateTime StartDat ...

最新文章

  1. 【 MATLAB 】nextpow2 函数用法之 Optimize FFT with Padding
  2. python装饰器_python装饰器完全指南之一
  3. java 连接janusgraph_基于JanusGraph的大数据图数据库
  4. 说说docker run的--detach
  5. python django django-debug-toolbar 加载缓慢,不能使用。
  6. python不同模块间传递数据_Python模块-数据传送模块
  7. chisel快速入门(二)
  8. 1982:【19CSPJ普及组】数字游戏
  9. Markdown--行内公式编辑
  10. ios build fdk-aac
  11. 杭州·云栖 2050 大会日程(5.25-5.27)
  12. macbook重装系统 选择方案_超详细的mac重装系统教程
  13. java jit_Java的JIT
  14. 人机交互-2-交互设计的原则与方法
  15. uni-app的灰朦层取消滑动以及官方弹出框设计代码
  16. 1934: [Shoi2007]Vote 善意的投票
  17. Substance风格无法设置水印效果的处理
  18. 在阿里晋升3次,4年拿下P8岗位,这份pdf或许对你有帮助
  19. ARM64启动过程分析
  20. 【学习笔记】| 移动应用开发Android (未完待更新)

热门文章

  1. Android SDK 2.3安装图文教程 Android模拟器上网设置
  2. 再见UE之VS Code初体验---实现远端Linux C开发配置
  3. 闲暇时间筛选一些网易云歌曲(Python)
  4. 编译原理 实验二 LL(1)分析法程序实现
  5. 多线程下的单例模式实现
  6. git和svn区别 git的常用指令
  7. Apache 的 POI提供API
  8. (附源码)计算机毕业设计ssm服装创意定制管理系统
  9. Web指纹识别器系列2:他山之石,可以攻玉
  10. 需求的最初形式:12306ng的需求小说