这更像是一个概念问题,不一定与任何特定技术相关.假设您在服务器上有一些数据库,一些REST/JSON API用于访问该数据库中的内容,一些移动客户端显示通过API检索的数据.
在客户端上有一些缓存机制并且只要客户端只读取就能够启用对数据的脱机访问会很好(在我的情况下,拒绝对脱机客户端的写访问以避免必须管理所有可能发生的令人讨厌的冲突).
似乎解决这个问题的一个好方法是在客户端上提供服务器数据库模型的子集,并将数据从服务器同步到客户端.然后,访问本地数据库可能会立即返回结果,但也会触发对服务器的更新请求.如果服务器返回修改后的数据,则客户端模型会同步其本地数据库并通知显示数据更改.
最终的目标当然是用户可以浏览信息而不管他的互联网连接的稳定性,并且只要他不修改任何数据,就不会受到连接对话或类似的烦恼.
现在从实现的角度来看......一方面将服务器数据库直接耦合到客户端数据库似乎是一个坏主意,因为它们可能来自不同的供应商.我想至少在数据库实现之上需要一个独立于供应商的模型.另一方面,将数据从服务器数据库转换为某种传输格式,而不是将其放回客户端数据库,这似乎是一个很大的开销.
有任何建议如何以优雅和可维护的方式解决这个问题?
下线时,我的服务工作者收到以下错误:
(unknown) #3016 An unknown error occurred when fetching the script
我的服务工作者看起来像这样:
var version = 'v1'
this.addEventListener('install', function(event){
event.waitUntil(
caches.open(version).then(cache => {
return cache.addAll([
'https://fonts.googleapis.com/icon?family=Material+Icons',
'https://fonts.googleapis.com/css?family=Open+Sans:400,600,300',
'./index.html'
])
})
)
})
this.addEventListener('fetch', function(event) {
event.respondWith(
caches.match(event.request).then(function(resp) {
// if it's not in the cache, server the regular network request. And save it to the cache
return resp || fetch(event.request).then(function(response) {
return caches.open(version).then(function(cache) {
cache.put(event.request, response.clone())
return response
})
})
})
)
})
Run Code Online (Sandbox Code Playgroud)
它位于顶级目录,紧邻index.html中的清单导入:
<link rel="manifest" href="/manifest.json">
我在我的条目js文件中导入服务工作者.然后立即注册.
require('tether-manifest.json')
import serviceWorker …Run Code Online (Sandbox Code Playgroud) javascript manifest offline-caching service-worker progressive-web-apps
要注册服务工作者,我可以打电话
navigator.serviceWorker.register('/worker.js')
Run Code Online (Sandbox Code Playgroud)
每次加载页面时都会检查更新版本worker.js.如果找到更新,则在关闭所有页面的选项卡然后重新打开之前,不会使用新工作程序.我读到的解决方案是:
self.addEventListener('install', function(event) {
event.waitUntil(self.skipWaiting());
});
self.addEventListener('activate', function(event) {
event.waitUntil(self.clients.claim());
});
Run Code Online (Sandbox Code Playgroud)
我可以理解skipWaiting部分,但到底是做clients.claim()什么的?我已经完成了一些简单的测试,即使没有它也似乎按预期工作.
如何以编程方式缓存/下载google map v2 tile?有可能吗?
Bcos根据这个prntscr.com/3cyiqf它是不可能的,但是我已经看到这个链接 TileProvider使用本地磁贴 我认为如果Android提供TileProvider类来加载/使用资产中的磁贴比它应该是可用于缓存/下载的东西以编程方式/运行时
我的实际要求是:
如果用户当时与互联网连接,他可以下载/缓存特定区域的磁贴,或者他可以在电话屏幕中下载/缓存可见地图,并且当他下线时,下载的地图应该是可见的.
到目前为止我做了什么:
我见过OSMDROID lib它们提供了非常好的功能,但问题是我只想使用Google Map V2
我已经检查过静态地图API,我也创建了一个用于下载图块的演示,但是他们返回了一个具有指定缩放级别的图像,所以在这种情况下,如果我使用静态地图api,用户只能看到1级别的地图,他们就不能能够放大/缩小所以不好.
结论:
我想知道Google Map V2是否提供了以编程方式/运行时下载/缓存地图图块的任何工具?
编辑
我可以使用谷歌地图引擎吗?
android offline-caching google-maps-api-2 osmdroid google-maps-engine
我正在测试HTML5离线应用程序.为此,我将停止本地Web服务器(IIS)并打开应用程序.它加载正常,但一旦请求服务器端API方法就失败了.
我想阻止它,而不是$ .get('/ api/method')从我的本地存储中读取数据.但我可以找到任何设施来了解我的应用程序是否脱机.
if (/* online */) {
// fire ajax
} else {
// ask localstorage
}
Run Code Online (Sandbox Code Playgroud)
我尝试使用navigation.onLine但似乎总是如此(至少我可以在Chrome中看到).
你有什么建议吗?
编辑:考虑到当前的答案.应用程序清楚地知道它是脱机的,因为它根据cache.manifest占用资源.这对我来说太荒谬了,客户需要做任何诡计和伎俩.我认为应该有一种简单的方法来检查当前模式.
该应用程序
我有一个Web应用程序,当前使用AppCache进行离线功能,因为系统用户需要离线创建文档.该文档首先是离线创建的,当互联网访问可用时,用户可以单击"同步",将文档发送到服务器并将其另存为修订版.更具体地说,应用程序不会将更改增量保存为修订版(修改的确切字段),而是保存整个文档的全部内容.换句话说,保存了"快照"文档.
问题
用户可以从不同的浏览器和设备登录并处理他们的文档.当他们单击"同步"时,如果服务器的文档较新,则整个客户端的版本将被服务器覆盖.这导致一个主要问题,如下图所示.
上面的场景是因为当前的实现不依赖于增量(小的更改)而是依赖于快照修订.
一些问题
1)我的研究表明,我应该将"同步"机制升级为以增量表示(可以独立应用的小变化).这是一个合理的方法吗?
2)每个delta应该独立应用吗?
2)根据我的研究,修订增量有一个数值而不是时间戳.它的价值应该是什么?我如何确保服务器和客户端都同意修订号应该是什么?
堆栈信息
javascript synchronization offline-caching indexeddb html5-appcache
我正在使用sw-precache通过Polymer CLI构建过程生成我的服务工作,因此它旨在更新更新文件的哈希,以表示需要更新缓存.但是我的更新内容没有在缓存中被替换,所以如果我用ctrl + r刷新它会得到一个旧版本但是如果我用ctrl + shift + r刷新则会得到新版本.原因可能是我的服务工作者没有更新.
该文件指出
如果服务工作文件中的字节差异与其当前的差异,则认为它是新的.
,但是如果我的新服务工作者没有更改字节呢?(如果只有一个哈希发生了变化就会发生).如何配置sw-precache以在每次新请求时更新服务工作?
html5 offline-caching service-worker progressive-web-apps sw-precache
我正在使用Firebase作为后端实现AngularJS Web应用程序; 它也应该脱机工作; 多用户同步问题应该非常有限,因为app - by design - 只允许离线时的新数据条目.
我了解Firebase具有脱机功能,从某种意义上说,客户端可以承受临时网络连接故障:任何写入操作都将被延迟并缓存,直到网络再次出现.
我问是否存在任何可能性(或者是否计划实施它)以扩展Firebase离线功能,以使客户端能够在本地缓存服务器上(部分)数据的快照,从而为客户提供完整的离线体验,也提供读取操作.
我看到第三部分Firebase包装器存在,但它的文档非常"有限"(要善待...... :-).一个原生解决方案应该是首选...
更新:Frank van Puffelen发表评论后,我更有资格证明我的问题:
*Firebase本身是否支持其Web API中的脱机数据访问,或者是否会很快支持?*
我使用localForage在网站上存储一些数据以使其脱机.
我想有一个键并附加到值/数组.
到目前为止,我只能计算如何从存储中检索整个键/值,然后再次追加并设置整个键/值.这似乎非常浪费,并且当键/值变大时可能会出现问题.
var obj = ...
localforage.getItem('documents', function(err, value) {
value.push(obj);
localforage.setItem('documents', value);
}
Run Code Online (Sandbox Code Playgroud)
有没有更有效的方法来做到这一点?注意性能问题的关键/值必须有多大.
我想下载一个在ExoPlayer中流式传输的视频.
另外,甚至在使用ExoPlayer之前,我HttpURLConnection从本地存储提供的输入流中下载了一个文件并播放该文件.这没关系,但是它并没有解决我的同步流和缓存问题.
ExoPlayer还提供了一个缓存系统,这些系统似乎只适用于DASH或HLS流类型.我没有使用这些,并希望缓存mp4与ExtractorRendererBuilder.(这里有相当广泛的主题:https://github.com/google/ExoPlayer/issues/420).
DefaultHttpDataSource确实有暴露的api,HttpURLConnection但我不确定我是否正在重用流.以下是ExoPlayer中提供的示例代码.
@Override
public void buildRenderers(DemoPlayer player) {
Allocator allocator = new DefaultAllocator(BUFFER_SEGMENT_SIZE);
Handler mainHandler = player.getMainHandler();
// Build the video and audio renderers.
DefaultBandwidthMeter bandwidthMeter = new DefaultBandwidthMeter(mainHandler, null);
DataSource dataSource = new DefaultUriDataSource(context, bandwidthMeter,userAgent);
ExtractorSampleSource sampleSource = new ExtractorSampleSource(uri,dataSource,allocator,
BUFFER_SEGMENT_COUNT * BUFFER_SEGMENT_SIZE, mainHandler, player, 0);
MediaCodecVideoTrackRenderer videoRenderer = new MediaCodecVideoTrackRenderer(context,
sampleSource, MediaCodecSelector.DEFAULT, MediaCodec.VIDEO_SCALING_MODE_SCALE_TO_FIT, 5000,
mainHandler, player, 50);
MediaCodecAudioTrackRenderer audioRenderer = new MediaCodecAudioTrackRenderer(sampleSource,
MediaCodecSelector.DEFAULT, null, true, …Run Code Online (Sandbox Code Playgroud) offline-caching ×10
javascript ×5
android ×3
html5 ×2
angularjs ×1
couchdb ×1
database ×1
exoplayer ×1
firebase ×1
frontend ×1
indexeddb ×1
localforage ×1
manifest ×1
offline ×1
offline-mode ×1
osmdroid ×1
pouchdb ×1
sw-precache ×1