我用的阿里cdn,根据玩家反馈,有少数玩家,在4G网络环境下热更新,会出现资源错乱的问题,无论怎么删除包重新下载,重新热更新都是一样的。按理来说,cocos端不存在像web版那样的浏览器缓存问题的把?之前就遇到过一个玩家,更新到了一个错误的资源,一直更新不到新资源,我让他在WIFI下重新下载,重新热更新就好了。
这种问题可能是cdn的问题,怎么从客户端这边杜绝这种问题呢?每次资源文件改变,能不能根据文件md5值,更改文件名加一个哈希值。重命名完之后,引擎怎么引用到正确的资源文件?
每次都更改需要更新的文件名称 就可以了 文件名称不同 就不会缓存
修改文件名很麻烦,每个版本用不同的url即可。比如 http://xxx.xxx.xxx/<version>/aaa.png
cdn 的需求我们在未来版本会添加,目前可能需要每次更新之后,手动清除 cdn 缓存,不会存在 web 版的浏览器缓存问题,但是 cdn 本身会有缓存。
楼上提出的也是一个可行的方案,修改 packageUrl 即可
方法很简单,有2个
1.CDN推送有变化更新的文件
2.自己生成一个资源版本值(可以是MD5),然后这些值放到project.json里面,在登陆时下载,然后改CCBoot.js里面的_loadResIterator方法在加载的realUrl(在调用loader.load之前修改)后面加上参数 ?m=xxxx
if( typeof realUrl=="string") { var relPath = realUrl.split("res/" + LANG + "/").pop(); var md5 = cc.game.config["files_version"] ? cc.game.config["files_version"][relPath] : null; if( md5 ) { if( self._noCacheRex.test(relPath) ) { realUrl += "&m=" + md5; } else { realUrl +="?m=" + md5; } } } loader.load(realUrl, url, item, function (err, data) {
如果用到ImageView动态加载图片,还需要改cocos2d/core/textures/CCTextureCache.js里面的_p.addImage方法
' tex = locTexs[url] = new cc.Texture2D(); var relPath = url; var md5 = cc.game.config["files_version"] ? cc.game.config["files_version"][relPath] : null; if( md5 ) { if( /\?/.test(relPath) ) { relPath += "&m=" + md5; } else { relPath +="?m=" + md5; } } tex.url = url; var basePath = cc.loader.getBasePath ? cc.loader.getBasePath() : cc.loader.resPath; cc.loader.loadImg(cc.path.join(basePath || "", relPath), function (err, img) {
原理就是CDN会按照不同的请求URL进行缓存,如果没有缓存过的会回源,每个CDN服务商策略是不是不一样我不太清楚,但我们用的CDN服务商是可以的
可以的,不过还是有点复杂,还要改代码。按照panda说的方法,不用改动代码,我现在采用这种方式了,省事。
更新的时候将remote-assets上传至一个新的路径,然后将原版本的热更新文件里面的version.manifest里面的版本号修改一下,manifestUrl指向 新目录的project.manifest,新目录的project.manifest 里面的packageUrl 也指向新目录 就可以了。
这种方式最大的问题就是每一个版本所有资源都要重新下载一次,对CDN成本是很高的,CDN回源是按流量算的,你们如果资源少就无所谓
不对吧,热更新机制是根据md5比较的,md5值一样的不会去下载啊
他说的是每一次都要重新上传一次吧?
上传占的是源服务器流量,这没多少
按描述,应该是地址没有变化,例如 cdnhost/res/data.json
MD5变化了,但去请求的地址是一样的,一般情况下需要去CDN后台主动推送,节点上的缓存才会更新。
没有后台推送的情况下就需要改变请求地址,文件名加参数或改文件路径,CDN匹配不到才会回源
是的,加了一层新目录,相当于一份全新的资源
我知道cdn一般都有刷新缓存,但这个东西有点不靠谱,已经遇到好几个用户反馈,更新错乱了。而且大部分是移动4G网络下更新出的问题。所以换新目录/改名字才是靠谱方式。
CDN更新推送是肯定不靠谱的,特别是更新文件大的时候,鬼知道什么时候能同步完,尤其一些小型网络提供商(如:长城宽带)自己也会有缓存,如果是要做的是过亿流水的大项目,千万不要用这个,玩家多了各种问题找上你。
用版本号做文件夹靠谱,这种方式我们用了5年了,保证能更到最新的文件。
CDN流量那点钱跟游戏收入比起来根本不算什么。
按照heyao216同学的办法,更改version.manifest下的版本号及remoteManifestUrl为新版本的地址,在热更新判断版本号的时候并不能检测到版本号的不同。。。
建议,packageUrl 用cdn地址,remoteManifestUrl, remoteVersionUrl就不要用cdn地址了,
每次有新更新的时间,手动刷新cdn缓存
mark
修改AssetsManagerEx.cpp代码 将
_downloader->createDownloadFileTask(unit.srcUrl, unit.storagePath, unit.customId);
改为
_downloader->createDownloadFileTask(unit.srcUrl+"?v="+_tempManifest->getVersion(), unit.storagePath, unit.customId);
配合cdn设置 不要忽略URL参数就解决了