Improved persistent RPC for unack requests
This commit is contained in:
parent
e914425b22
commit
0c60e18ea6
@ -492,36 +492,37 @@ public class CoapTransportResource extends AbstractCoapTransportResource {
|
|||||||
@Override
|
@Override
|
||||||
public void onToDeviceRpcRequest(UUID sessionId, TransportProtos.ToDeviceRpcRequestMsg msg) {
|
public void onToDeviceRpcRequest(UUID sessionId, TransportProtos.ToDeviceRpcRequestMsg msg) {
|
||||||
log.trace("[{}] Received RPC command to device", sessionId);
|
log.trace("[{}] Received RPC command to device", sessionId);
|
||||||
|
boolean sent = false;
|
||||||
try {
|
try {
|
||||||
Response response = coapTransportAdaptor.convertToPublish(isConRequest(), msg, rpcRequestDynamicMessageBuilder);
|
Response response = coapTransportAdaptor.convertToPublish(isConRequest(), msg, rpcRequestDynamicMessageBuilder);
|
||||||
int requestId = getNextMsgId();
|
int requestId = getNextMsgId();
|
||||||
response.setMID(requestId);
|
response.setMID(requestId);
|
||||||
|
|
||||||
if (msg.getPersisted()) {
|
if (msg.getPersisted() && isConRequest()) {
|
||||||
if (isConRequest()) {
|
transportContext.getRpcAwaitingAck().put(requestId, msg);
|
||||||
transportContext.getRpcAwaitingAck().put(requestId, msg);
|
transportContext.getScheduler().schedule(() -> {
|
||||||
transportContext.getScheduler().schedule(() -> {
|
TransportProtos.ToDeviceRpcRequestMsg awaitingAckMsg = transportContext.getRpcAwaitingAck().remove(requestId);
|
||||||
TransportProtos.ToDeviceRpcRequestMsg awaitingAckMsg = transportContext.getRpcAwaitingAck().remove(requestId);
|
if (awaitingAckMsg != null) {
|
||||||
if (awaitingAckMsg != null) {
|
transportService.process(sessionInfo, msg, true, TransportServiceCallback.EMPTY);
|
||||||
transportService.process(sessionInfo, msg, true, TransportServiceCallback.EMPTY);
|
}
|
||||||
}
|
}, Math.max(0, msg.getExpirationTime() - System.currentTimeMillis()), TimeUnit.MILLISECONDS);
|
||||||
}, Math.max(0, msg.getExpirationTime() - System.currentTimeMillis()), TimeUnit.MILLISECONDS);
|
response.addMessageObserver(new TbCoapMessageObserver(requestId, id -> {
|
||||||
response.addMessageObserver(new TbCoapMessageObserver(requestId, id -> {
|
TransportProtos.ToDeviceRpcRequestMsg rpcRequestMsg = transportContext.getRpcAwaitingAck().remove(id);
|
||||||
TransportProtos.ToDeviceRpcRequestMsg rpcRequestMsg = transportContext.getRpcAwaitingAck().remove(id);
|
if (rpcRequestMsg != null) {
|
||||||
if (rpcRequestMsg != null) {
|
transportService.process(sessionInfo, rpcRequestMsg, false, TransportServiceCallback.EMPTY);
|
||||||
transportService.process(sessionInfo, rpcRequestMsg, false, TransportServiceCallback.EMPTY);
|
}
|
||||||
}
|
}));
|
||||||
}));
|
|
||||||
} else {
|
|
||||||
transportService.process(sessionInfo, msg, false, TransportServiceCallback.EMPTY);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
exchange.respond(response);
|
exchange.respond(response);
|
||||||
|
sent = true;
|
||||||
} catch (AdaptorException e) {
|
} catch (AdaptorException e) {
|
||||||
log.trace("Failed to reply due to error", e);
|
log.trace("Failed to reply due to error", e);
|
||||||
closeObserveRelationAndNotify(sessionId, CoAP.ResponseCode.INTERNAL_SERVER_ERROR);
|
closeObserveRelationAndNotify(sessionId, CoAP.ResponseCode.INTERNAL_SERVER_ERROR);
|
||||||
closeAndDeregister();
|
closeAndDeregister();
|
||||||
|
} finally {
|
||||||
|
if (msg.getPersisted() && !isConRequest()) {
|
||||||
|
transportService.process(sessionInfo, msg, sent, TransportServiceCallback.EMPTY);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -17,6 +17,7 @@ package org.thingsboard.server.transport.mqtt;
|
|||||||
|
|
||||||
import com.fasterxml.jackson.databind.JsonNode;
|
import com.fasterxml.jackson.databind.JsonNode;
|
||||||
import com.google.gson.JsonParseException;
|
import com.google.gson.JsonParseException;
|
||||||
|
import io.netty.channel.ChannelFuture;
|
||||||
import io.netty.channel.ChannelHandlerContext;
|
import io.netty.channel.ChannelHandlerContext;
|
||||||
import io.netty.channel.ChannelInboundHandlerAdapter;
|
import io.netty.channel.ChannelInboundHandlerAdapter;
|
||||||
import io.netty.handler.codec.mqtt.MqttConnAckMessage;
|
import io.netty.handler.codec.mqtt.MqttConnAckMessage;
|
||||||
@ -825,20 +826,19 @@ public class MqttTransportHandler extends ChannelInboundHandlerAdapter implement
|
|||||||
try {
|
try {
|
||||||
deviceSessionCtx.getPayloadAdaptor().convertToPublish(deviceSessionCtx, rpcRequest).ifPresent(payload -> {
|
deviceSessionCtx.getPayloadAdaptor().convertToPublish(deviceSessionCtx, rpcRequest).ifPresent(payload -> {
|
||||||
int msgId = ((MqttPublishMessage) payload).variableHeader().packetId();
|
int msgId = ((MqttPublishMessage) payload).variableHeader().packetId();
|
||||||
if (rpcRequest.getPersisted()) {
|
if (rpcRequest.getPersisted() && isAckExpected(payload)) {
|
||||||
if (isAckExpected(payload)) {
|
rpcAwaitingAck.put(msgId, rpcRequest);
|
||||||
rpcAwaitingAck.put(msgId, rpcRequest);
|
context.getScheduler().schedule(() -> {
|
||||||
context.getScheduler().schedule(() -> {
|
TransportProtos.ToDeviceRpcRequestMsg awaitingAckMsg = rpcAwaitingAck.remove(msgId);
|
||||||
TransportProtos.ToDeviceRpcRequestMsg awaitingAckMsg = rpcAwaitingAck.remove(msgId);
|
if (awaitingAckMsg != null) {
|
||||||
if (awaitingAckMsg != null) {
|
transportService.process(deviceSessionCtx.getSessionInfo(), rpcRequest, true, TransportServiceCallback.EMPTY);
|
||||||
transportService.process(deviceSessionCtx.getSessionInfo(), rpcRequest, true, TransportServiceCallback.EMPTY);
|
}
|
||||||
}
|
}, Math.max(0, rpcRequest.getExpirationTime() - System.currentTimeMillis()), TimeUnit.MILLISECONDS);
|
||||||
}, Math.max(0, rpcRequest.getExpirationTime() - System.currentTimeMillis()), TimeUnit.MILLISECONDS);
|
}
|
||||||
} else {
|
var cf = publish(payload, deviceSessionCtx);
|
||||||
transportService.process(deviceSessionCtx.getSessionInfo(), rpcRequest, false, TransportServiceCallback.EMPTY);
|
if (rpcRequest.getPersisted() && !isAckExpected(payload)) {
|
||||||
}
|
cf.addListener(result -> transportService.process(deviceSessionCtx.getSessionInfo(), rpcRequest, result.cause() != null, TransportServiceCallback.EMPTY));
|
||||||
}
|
}
|
||||||
publish(payload, deviceSessionCtx);
|
|
||||||
});
|
});
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
log.trace("[{}] Failed to convert device RPC command to MQTT msg", sessionId, e);
|
log.trace("[{}] Failed to convert device RPC command to MQTT msg", sessionId, e);
|
||||||
@ -855,8 +855,8 @@ public class MqttTransportHandler extends ChannelInboundHandlerAdapter implement
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void publish(MqttMessage message, DeviceSessionCtx deviceSessionCtx) {
|
private ChannelFuture publish(MqttMessage message, DeviceSessionCtx deviceSessionCtx) {
|
||||||
deviceSessionCtx.getChannel().writeAndFlush(message);
|
return deviceSessionCtx.getChannel().writeAndFlush(message);
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isAckExpected(MqttMessage message) {
|
private boolean isAckExpected(MqttMessage message) {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user