# 短连接接入平台

默认情况下,使用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

以上代码仅作为演示功能逻辑,请根据实际情况进行相应的处理.