高级特性

离线事件

离线事件

在实时应用中,检测客户端是否断线是非常有必要的。例如,当一个用户的网络连接中断时,我们希望标记这个用户“离线”状态。

Wilddog提供了离线事件功能,使得客户端连接断开时,指定的数据被写入云数据库中。不论是客户端主动断开,还是意外的网络中断,甚至是客户端应用崩溃,这些数据写入动作都将会被执行。因此我们可以依靠这个功能,在用户离线的时候,做一些数据清理工作。Wilddog支持的所有数据写入动作,包括set, update,remove,都可以设置在离线事件中执行。

下面是一个例子,使用onDisconnect()方法,在离线的时候写入数据:

var presenceRef = new Wilddog('https://samplechat.wilddogio.com/disconnectmessage');
// 当客户端连接中断时,写入一个字符串
presenceRef.onDisconnect().set("I disconnected!");

离线事件是如何工作的

当进行了一个onDisconnect()调用之后,这个事件将会被记录在云端。云端会监控每一个客户端的连接。如果发生了超时,或者客户端主动断开连接,云端就触发记录的离线事件。

客户端可以通过回调方法,确保离线事件被云端正确记录了:

presenceRef.onDisconnect().remove( function(err) {
  if( err ) {
    console.error('could not establish onDisconnect event', err);
  }
});

要取消一个离线事件,可以使用cancel()方法:

var onDisconnectRef = presenceRef.onDisconnect();
onDisconnectRef.set('I disconnected');
// 要取消离线事件
onDisconnectRef.cancel();


检查连接状态

在许多应用场景下,客户端需要知道自己是否在线。Wilddog客户端提供了一个特殊的数据地址:/.info/connected。每当客户端的连接状态发生改变时,这个地址的数据都会被更新。

var connectedRef = new Wilddog("https://samplechat.wilddogio.com/.info/connected");
connectedRef.on("value", function(snap) {
  if (snap.val() === true) {
    alert("connected");
  } else {
    alert("not connected");
  }
});

/.info/connected的值是boolean类型的,它不会和云端进行同步。


云端时间戳

Wilddog提供了一种将云端时间戳作为数据写入的机制。这个机制和onDisconnect()方法组合起来,很容易实现记录客户端断线事件的功能:

var userLastOnlineRef = new Wilddog("https://samplechat.wilddogio.com/users/joe/lastOnline");
userLastOnlineRef.onDisconnect().set(Wilddog.ServerValue.TIMESTAMP);

另外,Wilddog提供一种查看本地时间和服务器时间差的机制。本地时间和客户端时间差保存在 /.info/serverTimeOffset 中,你可以通过on 或者once 监听 value 事件来获取这个数据:


var serverTsRef = new Wilddog("https://samplechat.wilddogio.com/.info/serverTimeOffset");
serverTsRef.on('value',function(snapshot){
  var offset = snapshot.val();
  serverTime = (new Date).getTime() + offset ; // 获取当前服务端时间
})

Transaction

当处理可能被并发更新导致损坏的复杂数据时,比如增量计数器,我们提供了事务操作。事务操作需要提供两个参数:一个更新方法和一个可选的完成 callback 方法。更新方法提供当前数据,当前数据是云端读取的。举例说明,如果我们想在一个的博文上计算点赞的数量,可以这样写一个事务:

var upvotesRef = new Wilddog('https://docs-examples.wilddogio.com/saving-data/wildblog/posts/-JRHTHaIs-jNPLXOQivY/upvotes');

upvotesRef.transaction(function (currentValue) {
  return (currentValue || 0) + 1;
});

我们使用currentValue || 0来判断计数器是否为空或者是自增加。 如果上面的代码没有使用事务, 当两个客户端在同时试图累加,那结果可能是为数字 1 且非数字 2。

注意:transaction()可能被多次被调用,必须处理 currentData 变量为 null 的情况。 当执行事务时,云端有数据存在,但是本地可能没有缓存,此时 currentData 为 null。

更多关于事务 API 的文档


安全域名

安全域名是指被野狗服务器信任的你的应用的域名。当你设置安全域名后,只有你的应用可以通过JavaScript SDK调用服务器资源。

当你开启安全域名时,在“安全域名白名单”中,为你的应用最多配置6个域名。例如输入域名 www.yourapp.com;同时支持域名泛匹配:允许填写 *.yourapp.com,这种形式则可以匹配app.yourapp.com,a1.app.yourapp.com域名作为安全域名。


R