You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
88 lines
2.8 KiB
88 lines
2.8 KiB
|
2 years ago
|
# 短连接接入平台
|
||
|
|
|
||
|
|
默认情况下,使用tcp和mqtt方式接入时,当连接断开时,则认为设备已离线。
|
||
|
|
但是在某些场景(如:低功率设备)下,无法使用长连接进行通信,可以通过指定特定配置使平台保持设备在线状态。
|
||
|
|
|
||
|
|
::: tip 说明
|
||
|
|
以下功能及API在`jetlinks 1.4.0` 后提供。
|
||
|
|
:::
|
||
|
|
|
||
|
|
## 保持在线
|
||
|
|
|
||
|
|
在自定义协议包解码出消息时,可通过在消息中添加头`keepOnline`来进行设置。如:
|
||
|
|
|
||
|
|
```java
|
||
|
|
|
||
|
|
message.addHeader(Headers.keepOnline,true); //设置让会话强制在线
|
||
|
|
message.addHeader(Headers.keepOnlineTimeoutSeconds,600);//设置超时时间(可选,默认10分钟),如果超过这个时间没有收到任何消息则认为离线。
|
||
|
|
|
||
|
|
```
|
||
|
|
|
||
|
|
::: tip 提示
|
||
|
|
|
||
|
|
MQTT接入时添加到任意消息即可。TCP接入时添加到`DeviceOnlineMessage`即可。
|
||
|
|
|
||
|
|
如果服务重启,将不会保存在线状态!
|
||
|
|
|
||
|
|
:::
|
||
|
|
|
||
|
|
## 缓存下发消息
|
||
|
|
|
||
|
|
在进行消息下发时,因为会话是强制保持在线的,所以消息会直接通过session下发,但是此时设备可能已经断开了连接,
|
||
|
|
将会抛出异常`DeviceOperationException(ErrorCode.CLIENT_OFFLINE)`。这时候可以通过将消息缓存起来,等待下次设备
|
||
|
|
连接上来后再下发指令。
|
||
|
|
|
||
|
|
一、在自定义协议包中使用消息拦截器拦截异常
|
||
|
|
|
||
|
|
```java
|
||
|
|
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);
|
||
|
|
});
|
||
|
|
}
|
||
|
|
});
|
||
|
|
|
||
|
|
```
|
||
|
|
|
||
|
|
二、获取缓存的消息
|
||
|
|
|
||
|
|
在收到设备指令后进行解码时,可以先获取是否有缓存到消息,然后发送到设备.
|
||
|
|
|
||
|
|
伪代码如下:
|
||
|
|
|
||
|
|
```java
|
||
|
|
|
||
|
|
@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
|
||
|
|
以上代码仅作为演示功能逻辑,请根据实际情况进行相应的处理.
|
||
|
|
:::
|