短连接接入平台
默认情况下,使用tcp和mqtt方式接入时,当连接断开时,则认为设备已离线。 但是在某些场景(如:低功率设备)下,无法使用长连接进行通信,可以通过指定特定配置使平台保持设备在线状态。
说明
以下功能及API在jetlinks 1.4.0
后提供。
保持在线
在自定义协议包解码出消息时,可通过在消息中添加头keepOnline
来进行设置。如:
message.addHeader(Headers.keepOnline,true); //设置让会话强制在线
message.addHeader(Headers.keepOnlineTimeoutSeconds,600);//设置超时时间(可选,默认10分钟),如果超过这个时间没有收到任何消息则认为离线。
提示
MQTT接入时添加到任意消息即可。TCP接入时添加到DeviceOnlineMessage
即可。
如果服务重启,将不会保存在线状态!
缓存下发消息
在进行消息下发时,因为会话是强制保持在线的,所以消息会直接通过session下发,但是此时设备可能已经断开了连接, 将会抛出异常DeviceOperationException(ErrorCode.CLIENT_OFFLINE)
。这时候可以通过将消息缓存起来,等待下次设备 连接上来后再下发指令。
一、在自定义协议包中使用消息拦截器拦截异常
support.addMessageSenderInterceptor(new DeviceMessageSenderInterceptor() {
@Override
public <R extends DeviceMessage> Flux<R> afterSent(DeviceOperator device, DeviceMessage message, Flux<R> reply) {
return reply.onErrorResume(DeviceOperationException.class, err -> {
if (err.getCode() == ErrorCode.CLIENT_OFFLINE) {
return device
.setConfig("will-msg", message) //设置到配置中
.thenReturn(((RepayableDeviceMessage<?>) message)
.newReply()
.code(ErrorCode.REQUEST_HANDLING.name())
.message("设备处理中...")
.success()
)
.map(r -> (R) r);
}
return Mono.error(err);
});
}
});
二、获取缓存的消息
在收到设备指令后进行解码时,可以先获取是否有缓存到消息,然后发送到设备.
伪代码如下:
@Override
public Mono<? extends Message> decode(MessageDecodeContext context) {
return context.getDevice()
.getAndRemoveConfig("will-msg")
.map(val -> val.as(DeviceMessage.class))
.flatMap((msg) -> {
return ((FromDeviceMessageContext) context)
.getSession()
.send(doEncode(msg)); //编码并发送给设备
})
.thenReturn(doDecode(context)); //解码收到的消息
}
TIP
以上代码仅作为演示功能逻辑,请根据实际情况进行相应的处理.