首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >CalDAV在JavaScript中的增量同步

CalDAV在JavaScript中的增量同步
EN

Stack Overflow用户
提问于 2020-05-24 11:01:28
回答 1查看 376关注 0票数 1

我希望从服务器获取CalDAV日历和通讯录,将值本地存储在磁盘上以缓存它们,并保存syncToken。然后,稍后,在某个时间间隔内或最迟在应用程序的下一次启动期间,再次运行同步。在第二次同步期间,我只想获得那些(以及确切地说是那些)被更改的日历条目和联系人(包括添加、删除或修改)。

我无法从lambdabaa/dav = npm dav的日历和地址簿同步API中了解如何做到这一点。文件没有描述这一点。有一个syncCalendar()函数,它从名称上应该可以完成我需要的事情,但是没有描述params和整个过程。在代码中,有一个syncToken (还有ctagetag)。我正在尝试使用syncToken,它应该能满足我的需要,但它没有。

同步之后,我获取calendar.syncToken并存储它,在下一次同步(可能是重新启动之后)之前,我恢复syncToken。但每次我都能完全同步。我似乎使用了错误的API,但我不知道什么是正确的。

专用测试用例:

  1. git clone https://github.com/benbucksch/test-dav-sync/
  2. yarn install
  3. yarn start

代码,自成一体

代码语言:javascript
复制
import dav from 'dav';
import config from './config.js'; /* Pseudo JSON File with:
export default
{
  "serverURL": "https://...hostname.../remote.php/dav",
  "username": "...",
  "password": "..."
}
*/

var gJSONSavedFile = {}; // would normally be a file or database table

async function start() {
  let syncToken = gJSONSavedFile.syncToken; // get it from file
  console.info("sync token from file", syncToken);

  console.time("calendar-connect");
  let xhr = new dav.transport.Basic(
    new dav.Credentials({
      username: config.username,
      password: config.password,
    })
  );
  let account = await dav.createAccount({
    server: config.serverURL,
    //loadCollections: false,
    //loadObjects: false,
    xhr: xhr,
  });
  console.timeEnd("calendar-connect");
  let calendar = account.calendars[0]; // just the first, just for testing
  console.time("calendar sync");
  console.log("sync token after init", calendar.syncToken);
  if (syncToken) {
    console.log("but setting sync token to", syncToken);
    calendar.syncToken = syncToken; // TODO Already set. Doesn't work.
  }
  calendar = await dav.syncCalendar(calendar, {
    syncToken: syncToken, // TODO Doesn't work
    xhr: xhr,
  });
  console.timeEnd("calendar sync");
  gJSONSavedFile.syncToken = calendar.syncToken; // save it
  console.log("sync token after sync", gJSONSavedFile.syncToken);
  console.log("Got", calendar.objects.length, "calendar entries");
}


(async () => {
  try {
    console.log("Test first start");
    await start();
    console.log("\nTest second start");
    await start();
  } catch (ex) {
    console.error(ex);
  }
})();

当针对NextCloud运行时,输出:

代码语言:javascript
复制
Test first start
sync token from file undefined
calendar-connect: 4.765s
sync token after init http://sabre.io/ns/sync/1157
calendar sync: 2.562s
sync token after sync http://sabre.io/ns/sync/1157
Got 1051 calendar entries

Test second start
sync token from file http://sabre.io/ns/sync/1157
calendar-connect: 3.351s
sync token after init http://sabre.io/ns/sync/1157
but setting sync token to http://sabre.io/ns/sync/1157
calendar sync: 2.510s
sync token after sync http://sabre.io/ns/sync/1157
Got 1051 calendar entries
Done in 13.29s.

预期产出将是:

  1. 第二个同步返回0项。
  2. calendar.syncToken不会在init和登录后立即设置。

事实上,syncToken已经设置在init之后,这表明我在这里误解了API。

EN

回答 1

Stack Overflow用户

发布于 2021-02-06 22:12:19

在深入分析dav库之后,我想出了如何与令牌同步。(实际上,请求的props部分花费的时间最多,因为文档非常差)

由于syncCollection只代表请求,因此需要手动发送请求,即需要执行以下操作:

  1. 创建您的请求:
代码语言:javascript
复制
var req = dav.request.syncCollection({
  syncLevel: 1,
  syncToken: "http://sabre.io/ns/sync/138", //here you need to put your token
  props: [{
    namespace: "DAV:",
    name: "getetag"
  }],
});
  1. 发送请求:
代码语言:javascript
复制
var result = await xhr.send(req, 'https://demo.calendar.com/dav/calendars/user_123/democalendar/')

这导致了以下反应:

代码语言:javascript
复制
result {
    responses: 
    [
       {
          href: '/dav/calendars/user_123/democalendar/4564659816516.ical',
          props: [Object]
       }
    ],
    syncToken: 'http://sabre.io/ns/sync/139'
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/61984977

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档