实时数据库(WebSocket)
该功能可实现订阅数据表的数据增删改变化,当表数据改变时,app 可以实时接收到数据的变化。
操作步骤
实例化
Table
对象发起订阅,接收事件
取消订阅
info 使用实时数据库功能前需要先进行登录操作
通过 tableName
或 tableId
实例化一个 Table
对象,操作该对象即相当于操作对应的数据表。
tableName
或 tableId
实例化一个 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"];
参数说明
tableName
和 tableId
二选一
Id
String
数据表的 Id
name
String
数据表名
info 实时数据库功能无法订阅内置数据表,如 _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);
}];
参数说明
where
Where?
否
查询条件订阅,默认为 nil,表示订阅事件所有的操作都会触发回调。
info 条件订阅使用方法与查询数据一致,可参考:查询数据。 Websocket 按条件订阅目前仅支持比较(compare)查询。
按条件订阅支持以下操作符:
String
=, !=
Int/Float/Double
=, >, >=, <, <=, !=
Bool
=, !=
Date
=, >, >=, <, <=, !=
另外,在知晓云控制台中手动删除数据时,如需触发删除数据动作的订阅通知,需要勾上「删除动作触发触发器」设置,如下图

取消订阅
当实时数据库功能连接成功后,会一直保持订阅状态。如需断开连接,比如退出发起订阅的页面时,可根据需要主动发起取消订阅。
Subscription
表示一个订阅对象,在订阅成功的回调函数获取,并保存,当需要取消订阅 时调用unsubscribe
方法。
func unsubscribe(onSuccess:onError:)
代码示例
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
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
错误码
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
连接错误
Last updated
Was this helpful?