处理网关获取升级包的请求(二)
继续啃硬骨头,真香
由于要再写一个方法getOtaPackageCallbackByGateway(),这又是一个难题,写代码是不可能的,这辈子都不可能写代码,只有ctrl+c ctrl+v 这种办法,才能勉强生存。
首先复制getOtaPackageCallback(),改名为getOtaPackageCallbackByGateway(),变成下面这样:
private void getOtaPackageCallbackByGateway(ChannelHandlerContext ctx, MqttPublishMessage mqttMsg, int msgId, Matcher fwMatcher, OtaPackageType type) {
String payload = mqttMsg.content().toString(UTF8);
int chunkSize = StringUtils.isNotEmpty(payload) ? Integer.parseInt(payload) : 0;
String requestId = fwMatcher.group("requestId");
int chunk = Integer.parseInt(fwMatcher.group("chunk"));
if (chunkSize > 0) {
this.chunkSizes.put(requestId, chunkSize);
} else {
chunkSize = chunkSizes.getOrDefault(requestId, 0);
}
if (chunkSize > context.getMaxPayloadSize()) {
sendOtaPackageError(ctx, PAYLOAD_TOO_LARGE);
return;
}
String otaPackageId = otaPackSessions.get(requestId);
if (otaPackageId != null) {
sendOtaPackage(ctx, mqttMsg.variableHeader().packetId(), otaPackageId, requestId, chunkSize, chunk, type);
} else {
TransportProtos.SessionInfoProto sessionInfo = deviceSessionCtx.getSessionInfo();
TransportProtos.GetOtaPackageRequestMsg getOtaPackageRequestMsg = TransportProtos.GetOtaPackageRequestMsg.newBuilder()
.setDeviceIdMSB(sessionInfo.getDeviceIdMSB())
.setDeviceIdLSB(sessionInfo.getDeviceIdLSB())
.setTenantIdMSB(sessionInfo.getTenantIdMSB())
.setTenantIdLSB(sessionInfo.getTenantIdLSB())
.setType(type.name())
.build();
transportService.process(deviceSessionCtx.getSessionInfo(), getOtaPackageRequestMsg,
new OtaPackageCallback(ctx, msgId, getOtaPackageRequestMsg, requestId, chunkSize, chunk));
}
}
仔细观察,前面一大坨是在提取参数,我们需要的参数肯定跟它不一样,我们请求的参数有4个,分别是requestId、chunk、chunkSize、deviceName。我们先修改提取参数部分,我修改后如下:
@Data
private class GatewayOtaPackageRequestDTO {
private String deviceName;
private Integer chunkSize;
}
private void getOtaPackageCallbackByGateway(ChannelHandlerContext ctx, MqttPublishMessage mqttMsg, int msgId, Matcher fwMatcher, OtaPackageType type) {
String requestId = fwMatcher.group("requestId");
int chunk = Integer.parseInt(fwMatcher.group("chunk"));
String payload = mqttMsg.content().toString(UTF8);
Gson gson = new Gson();
GatewayOtaPackageRequestDTO dto = null;
try {
dto = gson.fromJson(payload, GatewayOtaPackageRequestDTO.class);
} catch (JsonSyntaxException e){
sendOtaPackageErrorToGateway(ctx, msgId, requestId, "解析JSON出错,请求负载不合法,负载示例:{deviceName:"SN-001", chunkSize:512}", type);
return;
}
if(dto == null) {
sendOtaPackageErrorToGateway(ctx, msgId, requestId, "请求没有负载,负载示例:{deviceName:"SN-001", chunkSize:512}", type);
return;
}
Integer chunkSize = dto.getChunkSize();
String deviceName = dto.getDeviceName();
if(chunkSize == null) {
sendOtaPackageErrorToGateway(ctx, msgId, requestId, "请求负载缺少chunkSize,负载示例:{deviceName:"SN-001", chunkSize:512}", type);
return;
}
if(deviceName == null) {
sendOtaPackageErrorToGateway(ctx, msgId, requestId, "请求负载缺少deviceName,负载示例:{deviceName:"SN-001", chunkSize:512}", type);
return;
}
if (chunkSize > 0) {
this.chunkSizes.put(requestId, chunkSize);
} else {
chunkSize = chunkSizes.getOrDefault(requestId, 0);
}
if (chunkSize > context.getMaxPayloadSize()) {
sendOtaPackageError(ctx, PAYLOAD_TOO_LARGE);
return;
}
String otaPackageId = otaPackSessions.get(requestId);
if (otaPackageId != null) {
sendOtaPackage(ctx, mqttMsg.variableHeader().packetId(), otaPackageId, requestId, chunkSize, chunk, type);
} else {
TransportProtos.SessionInfoProto sessionInfo = deviceSessionCtx.getSessionInfo();
TransportProtos.GetOtaPackageRequestMsg getOtaPackageRequestMsg = TransportProtos.GetOtaPackageRequestMsg.newBuilder()
.setDeviceIdMSB(sessionInfo.getDeviceIdMSB())
.setDeviceIdLSB(sessionInfo.getDeviceIdLSB())
.setTenantIdMSB(sessionInfo.getTenantIdMSB())
.setTenantIdLSB(sessionInfo.getTenantIdLSB())
.setType(type.name())
.build();
transportService.process(deviceSessionCtx.getSessionInfo(), getOtaPackageRequestMsg,
new OtaPackageCallback(ctx, msgId, getOtaPackageRequestMsg, requestId, chunkSize, chunk));
}
}
sendOtaPackageErrorToGateway()方法暂时不用管,它的作用是向网关发送错误响应,虽然多了很多判断,搞得代码多出不少行,但也是没有办法,反正是复制粘贴而来,也不费什么工夫。
这篇文章字数感觉挺多了,下一篇继续。