实时数据库(WebSocket)

该功能可实现订阅数据表的数据增删改变化,当表数据改变时,app 可以实时接收到数据的变化。

操作步骤

  1. 实例化 Table 对象
  2. 发起订阅,接收事件
  3. 取消订阅

使用实时数据库功能前需要先进行登录操作

通过 tableNametableId 实例化一个 Table 对象,操作该对象即相当于操作对应的数据表。

示例代码

// 通过 tableId 创建数据表实例 
let table = Table(Id: "1236")

// 通过 tablename 创建数据表实例
let table = Table(name: "danmu")
// 通过 tableId 创建数据表实例
BaaSTable *table = [[BaaSTable alloc] initId:@"1236"];

// 通过 tablename 创建数据表实例
BaaSTable *table = [[BaaSTable alloc] initWithName:@"danmu"];

参数说明

tableNametableId 二选一

名称 类型 说明
Id String 数据表的 Id
name String 数据表名

实时数据库功能无法订阅内置数据表,如 _userprofile 表、_richtextcontent 表等

发起数据表订阅操作

订阅数据表的事件,同时可以指定事件的查询条件,当满足条件的事件发生时,app 将会收到事件回调。

public func subscribe(event:where:onInit:onError:onEvent:)

示例代码

弹幕表 danmu,其中一个字段 type 表示弹幕类型:system 为系统弹幕,user 为用户弹幕,app 订阅新建一个类型为 user 的记录的事件,即每当有类型为 user 的记录创建时,app 将会收到事件回调。

let danmuTable = Table(name: "danmu")

// 给事件添加条件
let typeWhere = Where.compare("type", operator: .equalTo, value: "user")

// 发起订阅
danmuTable.subscribe(.onCreate, where: typeWhere) { [weak self] (subscription) in
    // 订阅成功,
    // 获得订阅对象 subscription,可通过 subscription 对象的 unsubscribe 方法取消该订阅。
    self?.subscription = subscription
} onError: { error in
    print("订阅失败: \(error?.localizedDescription ?? "")")
} onEvent: { (result) in
    print("事件触发 result: \(result ?? [:])")
}
BaaSSubscription *subscription = nil;
BaaSTable *table = [[BaaSTable alloc] initWithName:@"danmu"];

// 给事件添加条件
BaaSWhere *where = [BaaSWhere compare:@"type" operator:BaaSOperatorEqualTo value:@"user"];

// 发起订阅
[table subscribe:BaaSSubscriptionEventOnCreate where:where onInit:^(BaaSSubscription * _Nonnull subscription) {
    // 订阅成功,
    // 获得订阅对象 subscription,可通过 subscription 对象的 unsubscribe 方法取消该订阅。
    self.subscription = subscription;
} onError:^(NSError * _Nullable error) {
    NSLog(@"订阅错误:%@", error.localizedDescription);
} onEvent:^(NSDictionary<NSString *,id> * _Nullable result) {
    NSLog(@"事件触发:%@", result);
}];

参数说明

名称 类型 必填 说明
event SubscriptionEvent 表数据变化的类型,参考 SubscriptionEvent
where Where? 查询条件订阅,默认为 nil,表示订阅事件所有的操作都会触发回调。
onInit SubscribeCallback 订阅成功回调函数,参考 SubscribeCallback
onError ErrorSubscribeCallback 订阅失败回调函数,参考 ErrorSubscribeCallback
onEvent EventCallback 事件发生时的回调函数,参考 EventCallback

条件订阅使用方法与查询数据一致,可参考:查询数据。 Websocket 按条件订阅目前仅支持比较(compare)查询。

按条件订阅支持以下操作符:

数据类型 可使用的查询操作
String =, !=
Int/Float/Double =, >, >=, <, <=, !=
Bool =, !=
Date =, >, >=, <, <=, !=

另外,在知晓云控制台中手动删除数据时,如需触发删除数据动作的订阅通知,需要勾上「删除动作触发触发器」设置,如下图

删除数据触发 WebSocket
删除数据触发 WebSocket

取消订阅

当实时数据库功能连接成功后,会一直保持订阅状态。如需断开连接,比如退出发起订阅的页面时,可根据需要主动发起取消订阅。

Subscription 表示一个订阅对象,在订阅成功的回调函数获取,并保存,当需要取消订阅 时调用unsubscribe 方法。

func unsubscribe(onSuccess:onError:)
名称 类型 必填 说明
onSuccess UnsubscribeCallback 取消订阅成功回调函数,参考 UnsubscribeCallback
onError ErrorUnsubscribeCallback 取消订阅失败回调函数,参考 ErrorUnsubscribeCallback

代码示例

var subscription: Subscription?

let danmuTable = Table(name: "danmu")
danmuTable.subscribe(.onCreate) { [weak self] (subscription) in
    // 订阅成功
    // 获取订阅对象
     self?.subscription = subscription
} onError: { error in
    print("error: \(error?.localizedDescription ?? "")")
} onEvent: { (result) in
    print("result: \(result ?? [:])")
}
...

// 取消订阅
subscription?.unsubscribe(onSuccess: {
    print("取消订阅成功")
}, onError: { (error) in
    print("error: \(error?.localizedDescription ?? "")")
})

BaaSSubscription *subscription = nil;
BaaSTable *table = [[BaaSTable alloc] initWithName:@"danmu"];

[table subscribe:BaaSSubscriptionEventOnCreate where:nil onInit:^(BaaSSubscription * _Nonnull subscription) {
    // 订阅成功,
    // 获得订阅对象 subscription
    self.subscription = subscription;
} onError:^(NSError * _Nullable error) {
    NSLog(@"订阅错误:%@", error.localizedDescription);
} onEvent:^(NSDictionary<NSString *,id> * _Nullable result) {
    NSLog(@"事件触发:%@", result);
}];

... 

// 取消订阅
[subscription unsubscribeOnSuccess:^{
    NSLog(@"取消订阅成功");
} onError:^(NSError * _Nullable error) {
    NSLog(@"取消订阅错误:%@", error.localizedDescription);
}];

连接管理与重连

SDK 自动管理 WebSocket 的连接,当发起第一个订阅时,SDK 将建立连接,之后的订阅/接收事件/删除订阅,都使用该连接。当前无订阅时,SDK 主动关闭连接。

若 WebSocket 连接意外断开,比如 app 挂起,无网络等,当 app 恢复正常时,SDK 自动重连。

重连机制

SDK 提供了 ConnectionRetryPolicy 默认的重连机制。通过 delayLimit 可以设置下次连接的最大延时。其内部使用二进制退避算法实现重连延时控制,即 delay 秒后重新尝试连接,且不断重连,直到连接成功:

 var delay = (2^ retryCount) * 0.5
 delay = min(delay, delayLimit)

自定义重连机制

如果默认的重连机制不满足使用需求,可以自定义重连机制。SDK 提供了 ConnectionRetrier 协议,通过实现该协议的 retry(retryCount:) -> TimeInterval 方法,来自定义重连机制。该方法的参数为当前的重试次数,返回值为下次连接延时。如果返回值小于 0,表示不进行重连。

例如,重连机制为重试5次,延时从 1 秒开始,每次延时翻倍:

class ConnectionRetryOnePolicy: ConnectionRetrier {

    var retryLimit: UInt = 10 // 最大尝试次数

    init(retryLimit: UInt) {
        self.retryLimit = retryLimit
    }

    func retry(retryCount: UInt) -> TimeInterval {

        if retryCount < retryLimit {
            return 2 * retryCount * 0.5
        } else {
            return -1
        }
    }
}

// 设置重连机制
BaaSWebSocketConfiguration.retryPolicy = ConnectionRetryOnePolicy(retryLimit: 10)

数据类型

SubscriptionEvent

enum 类型,表示可订阅的事件类型,目前支持的类型有:

SubscriptionEvent

| 名称  | 说明  | 
| :---- | :---- |
| onCreate | 当数据表中有新的满足条件的记录被创建时,create 事件会被触发 |
| onUpdate | 当数据表中有满足条件的记录被更新时,update 事件会被触发 |
| onDelete | 当数据表中有新的满足条件的记录被删除时,delete 事件会被触发 |
BaaSSubscriptionEvent

| 名称  | 说明  | 
| :---- | :---- |
| BaaSOnCreate | 当数据表中有新的满足条件的记录被创建时,create 事件会被触发 |
| BaaSOnUpdate | 当数据表中有满足条件的记录被更新时,update 事件会被触发 |
| BaaSOnDelete | 当数据表中有新的满足条件的记录被删除时,delete 事件会被触发 |

SubscribeCallback

订阅成功回调函数

public typealias SubscribeCallback = (_ subscription: Subscription) -> Void
名称 类型 说明
subscription Subscription 表示一个订阅,可用于取消订阅

ErrorSubscribeCallback

订阅失败回调函数

public typealias ErrorSubscribeCallback = (_ error: NSError?) -> Void
名称 类型 说明
error NSError 订阅失败的错误信息,参考错误处理和错误码订阅错误信息

EventCallback

事件发生时的回调函数

public typealias EventCallback = (_ result: [String: Any]?) -> Void
名称 类型 说明
result [String: Any]? 回调信息

回调信息根据事件类型不同而不同,具体如下:

onCreate 事件类型得到的对象:

名称 类型 说明
event String 事件类型,返回 "on_create"
schema_id Number 订阅的数据表的 ID
schema_name String 订阅的数据表的表名
id String 新增的数据行的 ID
after Object 新增的数据行对象
before Object 空对象

示例

{
  "after": {
    "text": "123",
    "_read_perm": ["user:anonymous"],
    "_write_perm": ["user:anonymous"],
    "created_at": 1594265027,
    "updated_at": 1594265027,
    "created_by": 195448780235670,
    "id": "5f068dc32dc610747781efcc"
  },
  "before": {},
  "event": "on_create",
  "schema_id": 968,
  "schema_name": "product",
  "id": "5f068dc32dc610747781efcc"
}

onUpdate 事件类型得到的对象:

名称 类型 说明
event String 事件类型,返回 "on_update"
schema_id Number 订阅的数据表的 ID
schema_name String 订阅的数据表的表名
id String 更新的数据行的 ID
after Object 更新后的数据行对象
before Object 更新前的数据行对象

示例

{
  "after": {
    "text": "123123",
    "_read_perm": ["user:anonymous"],
    "_write_perm": ["user:anonymous"],
    "created_at": 1594265027,
    "updated_at": 1594265113,
    "created_by": 195448780235670,
    "id": "5f068dc32dc610747781efcc"
  },
  "before": {
    "text": "123",
    "_read_perm": ["user:anonymous"],
    "_write_perm": ["user:anonymous"],
    "created_at": 1594265027,
    "updated_at": 1594265027,
    "created_by": 195448780235670,
    "id": "5f068dc32dc610747781efcc"
  },
  "event": "on_update",
  "schema_id": 968,
  "schema_name": "product",
  "id": "5f068dc32dc610747781efcc"
}

onDelete 事件类型得到的对象:

名称 类型 说明
event String 事件类型,返回 "on_delete"
schema_id Number 订阅的数据表的 ID
schema_name String 订阅的数据表的表名
id String 删除的数据行的 ID
after Object 空对象
before Object 删除前的数据行对象

示例

{
  "after": {},
  "before": {
    "text": "123123",
    "_read_perm": ["user:anonymous"],
    "_write_perm": ["user:anonymous"],
    "created_at": 1594265027,
    "updated_at": 1594265113,
    "created_by": 195448780235670,
    "id": "5f068dc32dc610747781efcc"
  },
  "event": "on_delete",
  "schema_id": 968,
  "schema_name": "product",
  "id": "5f068dc32dc610747781efcc"
}

UnsubscribeCallback

取消订阅事件成功时的回调函数

public typealias UnsubscribeCallback = () -> Void

ErrorUnsubscribeCallback

取消订阅事件失败时的回调函数

public typealias ErrorUnsubscribeCallback = (_ error: NSError?) -> Void
名称 类型 说明
error NSError? 取消订阅失败的错误信息,参考错误处理和错误码订阅错误信息

错误码

错误码 错误描述 说明
400 duplicate subscription 重复订阅
400 not allow to subscribe builtin schema 不允许订阅内置表
400 invalid options 订阅的字段或值类型错误
400 schema does not exists 订阅的数据表不存在
400 no such subscription 取消订阅无效的订阅
402 payment required 应用欠费
500 internal server error 服务器错误
604 please login in 用户未登录
616 connection error 连接错误

results matching ""

    powered by

    No results matching ""