|
|
|
|
@ -24,10 +24,25 @@ public class EchoServerHandler extends ChannelInboundHandlerAdapter {
|
|
|
|
|
|
|
|
|
|
List<DeviceCodeParamEntity> deviceCodeParamList; |
|
|
|
|
|
|
|
|
|
// 调用service层的接口信息
|
|
|
|
|
// 调用service层的接口信息(懒加载,避免启动时Spring容器未就绪导致NPE)
|
|
|
|
|
private DeviceCodeParamService deviceCodeParamService; |
|
|
|
|
private GatewayManageService gatewayManageService; |
|
|
|
|
|
|
|
|
|
private DeviceCodeParamService getDeviceCodeParamService() { |
|
|
|
|
if (deviceCodeParamService == null) { |
|
|
|
|
ApplicationContext context = SpringBeanUtil.getApplicationContext(); |
|
|
|
|
deviceCodeParamService = context.getBean(DeviceCodeParamService.class); |
|
|
|
|
} |
|
|
|
|
return deviceCodeParamService; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
private GatewayManageService getGatewayManageService() { |
|
|
|
|
if (gatewayManageService == null) { |
|
|
|
|
ApplicationContext context = SpringBeanUtil.getApplicationContext(); |
|
|
|
|
DeviceCodeParamService deviceCodeParamService = context.getBean(DeviceCodeParamService.class); |
|
|
|
|
GatewayManageService gatewayManageService = context.getBean(GatewayManageService.class); |
|
|
|
|
gatewayManageService = context.getBean(GatewayManageService.class); |
|
|
|
|
} |
|
|
|
|
return gatewayManageService; |
|
|
|
|
} |
|
|
|
|
/** |
|
|
|
|
* 空闲次数 |
|
|
|
|
*/ |
|
|
|
|
@ -39,6 +54,8 @@ public class EchoServerHandler extends ChannelInboundHandlerAdapter {
|
|
|
|
|
private String IP; |
|
|
|
|
private String port; |
|
|
|
|
private String receiveStr = ""; |
|
|
|
|
// 限制最大接收字符串长度,防止内存溢出
|
|
|
|
|
private static final int MAX_RECEIVE_STR_LENGTH = 4096; |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* 客户端连接会触发 |
|
|
|
|
@ -59,6 +76,11 @@ public class EchoServerHandler extends ChannelInboundHandlerAdapter {
|
|
|
|
|
IdleStateEvent event = (IdleStateEvent) obj; |
|
|
|
|
if (IdleState.READER_IDLE.equals(event.state())) { //如果读通道处于空闲状态,说明没有接收到心跳命令
|
|
|
|
|
log.info("第{}已经10秒没有接收到客户端的信息了", idleCount); |
|
|
|
|
// 打印发送没有响应的日志
|
|
|
|
|
if (deviceCodeParamList != null && deviceCodeParamList.size() > 0 && num < deviceCodeParamList.size()) { |
|
|
|
|
String sendStr = deviceCodeParamList.get(num).getStrData(); |
|
|
|
|
log.error("网关端口:{} 发送的指令无响应:{}", port, sendStr); |
|
|
|
|
} |
|
|
|
|
receiveStr = ""; |
|
|
|
|
num = num + 1; |
|
|
|
|
if (num > size - 1) { |
|
|
|
|
@ -95,10 +117,15 @@ public class EchoServerHandler extends ChannelInboundHandlerAdapter {
|
|
|
|
|
receiveStr = receiveStr + ExchangeStringUtil.bytesToHexString(bytes);//将接收到的数据转为字符串,此字符串就是客户端发送的字符串
|
|
|
|
|
receiveStr = receiveStr.replace("null", ""); //去null
|
|
|
|
|
receiveStr = receiveStr.replace(" ", ""); //去空格
|
|
|
|
|
// 检查接收字符串长度,超过限制则清空,防止内存溢出
|
|
|
|
|
if (receiveStr.length() > MAX_RECEIVE_STR_LENGTH) { |
|
|
|
|
log.warn("接收到的数据超过最大长度限制,清空缓冲区, 当前长度:{}, 网关端口:{}", receiveStr.length(), port); |
|
|
|
|
receiveStr = ""; |
|
|
|
|
} |
|
|
|
|
//log.info("channelRead接收到的数据:" + receiveStr + ",length:" + receiveStr.length());
|
|
|
|
|
} |
|
|
|
|
} catch (Exception e) { |
|
|
|
|
log.error("channelRead异常", e); |
|
|
|
|
log.error("channelRead异常, 网关端口:{}", port, e); |
|
|
|
|
} finally { |
|
|
|
|
ReferenceCountUtil.release(msg); |
|
|
|
|
} |
|
|
|
|
@ -119,12 +146,12 @@ public class EchoServerHandler extends ChannelInboundHandlerAdapter {
|
|
|
|
|
// 清空receiveStr
|
|
|
|
|
receiveStr = ""; |
|
|
|
|
// 更新对应的网关在线情况
|
|
|
|
|
gatewayManageService.updateGatewayManage2(port); |
|
|
|
|
getGatewayManageService().updateGatewayManage2(port); |
|
|
|
|
//根据端口或者IP或者心跳包查询网关对应的项目名称
|
|
|
|
|
String projectName = gatewayManageService.selectProjectName(port); |
|
|
|
|
String projectName = getGatewayManageService().selectProjectName(port); |
|
|
|
|
log.info("---------------------{}项目网关上线---------------------", projectName); |
|
|
|
|
// 生成采集指令
|
|
|
|
|
deviceCodeParamList = deviceCodeParamService.queryCodeParam(port); //心跳包包含网关端口(自己定义返回心跳包)
|
|
|
|
|
deviceCodeParamList = getDeviceCodeParamService().queryCodeParam(port); //心跳包包含网关端口(自己定义返回心跳包)
|
|
|
|
|
size = deviceCodeParamList.size(); |
|
|
|
|
log.info("deviceCodeParam size ===> {}", size); |
|
|
|
|
num = 0; |
|
|
|
|
@ -205,11 +232,41 @@ public class EchoServerHandler extends ChannelInboundHandlerAdapter {
|
|
|
|
|
AnalysisReceiveOrder485 analysisReceiveOrder485 = new AnalysisReceiveOrder485(); |
|
|
|
|
analysisReceiveOrder485.analysisReceiveOrder485(receiveStr, deviceCodeParamEntity); |
|
|
|
|
// 根据项目id更新网关在线
|
|
|
|
|
gatewayManageService.updateGatewayManage2(deviceCodeParamEntity.getDataPort()); |
|
|
|
|
getGatewayManageService().updateGatewayManage2(deviceCodeParamEntity.getDataPort()); |
|
|
|
|
}); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* 白色网关发送下一个采集指令(减少重复代码) |
|
|
|
|
*/ |
|
|
|
|
private void whiteGatewaySendNextOrder(ChannelHandlerContext ctx, String snr, String ip) throws InterruptedException { |
|
|
|
|
num = num + 1; |
|
|
|
|
if (num > size - 1) { |
|
|
|
|
num = 0; |
|
|
|
|
Thread.sleep(200); |
|
|
|
|
SendOrderUtils.sendAllOrder2(deviceCodeParamList.get(num), ctx, snr, ip, num, size); |
|
|
|
|
log.info("------一轮采集完成,继续下一轮--------"); |
|
|
|
|
} else { |
|
|
|
|
if (Constant.WEB_FLAG) { |
|
|
|
|
log.info("not send code and close collection!"); |
|
|
|
|
num = 0; |
|
|
|
|
receiveStr = ""; |
|
|
|
|
ctx.close(); |
|
|
|
|
} else { |
|
|
|
|
Thread.sleep(200); |
|
|
|
|
SendOrderUtils.sendAllOrder2(deviceCodeParamList.get(num), ctx, snr, ip, num, size); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
private void whiteGateway(ChannelHandlerContext ctx) throws InterruptedException { |
|
|
|
|
// 添加字符串长度检查,防止StringIndexOutOfBoundsException
|
|
|
|
|
if (receiveStr == null || receiveStr.length() < 8) { |
|
|
|
|
log.warn("白色网关接收数据长度不足,跳过处理, 长度:{}, 网关端口:{}", receiveStr != null ? receiveStr.length() : 0, port); |
|
|
|
|
receiveStr = ""; |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (receiveStr.substring(0, 2).equalsIgnoreCase("2b") && receiveStr.substring(6, 8).equalsIgnoreCase("7b")) { |
|
|
|
|
receiveStr = receiveStr.substring(6); |
|
|
|
|
} |
|
|
|
|
@ -243,9 +300,9 @@ public class EchoServerHandler extends ChannelInboundHandlerAdapter {
|
|
|
|
|
Thread.sleep(200); |
|
|
|
|
ctx.channel().writeAndFlush(buffer); //发送数据
|
|
|
|
|
// 更新对应的网关在线情况
|
|
|
|
|
gatewayManageService.updateGatewayManage2(port); |
|
|
|
|
getGatewayManageService().updateGatewayManage2(port); |
|
|
|
|
// 生成采集指令
|
|
|
|
|
deviceCodeParamList = deviceCodeParamService.queryCodeParam(port); //心跳包包含网关端口(自己定义返回心跳包)
|
|
|
|
|
deviceCodeParamList = getDeviceCodeParamService().queryCodeParam(port); //心跳包包含网关端口(自己定义返回心跳包)
|
|
|
|
|
size = deviceCodeParamList.size(); |
|
|
|
|
log.info("白色网关接收长度===> " + size); |
|
|
|
|
num = 0; |
|
|
|
|
@ -282,111 +339,30 @@ public class EchoServerHandler extends ChannelInboundHandlerAdapter {
|
|
|
|
|
// 解析采集的报文,并保存到数据库
|
|
|
|
|
AnalysisReceiveOrder485 analysisReceiveOrder485 = new AnalysisReceiveOrder485(); |
|
|
|
|
analysisReceiveOrder485.analysisMeterOrder485(dataStr, deviceCodeParamList.get(num)); //电表报文解析
|
|
|
|
|
// 清空dataStr
|
|
|
|
|
// 判断发送的下标,如果不等于指令数组大小
|
|
|
|
|
num = num + 1; |
|
|
|
|
if (num > size - 1) { |
|
|
|
|
num = 0; |
|
|
|
|
Thread.sleep(200); |
|
|
|
|
// 继续发送下一个采集指令
|
|
|
|
|
SendOrderUtils.sendAllOrder2(deviceCodeParamList.get(num), ctx, port, IP, num, size); |
|
|
|
|
log.info("------一轮采集完成,继续下一轮--------"); |
|
|
|
|
} else { |
|
|
|
|
// 添加一个状态值,判断是否继续发送指令 update by ljf on 2020-08-07
|
|
|
|
|
if (Constant.WEB_FLAG) { |
|
|
|
|
num = 0; |
|
|
|
|
// 关闭连接
|
|
|
|
|
dataStr = null; |
|
|
|
|
ctx.close(); |
|
|
|
|
} else { |
|
|
|
|
Thread.sleep(200); |
|
|
|
|
// 继续发送下一个采集指令
|
|
|
|
|
SendOrderUtils.sendAllOrder2(deviceCodeParamList.get(num), ctx, port, IP, num, size); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
dataStr = ""; |
|
|
|
|
// 使用提取的方法发送下一个指令
|
|
|
|
|
whiteGatewaySendNextOrder(ctx, port, IP); |
|
|
|
|
} else if (dataStr.length() == 12 || dataStr.length() == 14) { |
|
|
|
|
log.info("白色网关冷水机接收===>" + dataStr); |
|
|
|
|
// 解析采集的报文,并保存到数据库
|
|
|
|
|
AnalysisReceiveOrder485 analysisReceiveOrder485 = new AnalysisReceiveOrder485(); |
|
|
|
|
analysisReceiveOrder485.analysisChillerOrder485(dataStr, deviceCodeParamList.get(0)); |
|
|
|
|
// 清空dataStr
|
|
|
|
|
dataStr = ""; |
|
|
|
|
// 判断发送的下标,如果不等于指令数组大小
|
|
|
|
|
num = num + 1; |
|
|
|
|
if (num > size - 1) { |
|
|
|
|
num = 0; |
|
|
|
|
Thread.sleep(200); |
|
|
|
|
// 继续发送下一个采集指令
|
|
|
|
|
SendOrderUtils.sendAllOrder2(deviceCodeParamList.get(num), ctx, port, IP, num, size); |
|
|
|
|
log.info("------一轮采集完成,继续下一轮--------"); |
|
|
|
|
} else { |
|
|
|
|
// 添加一个状态值,判断是否继续发送指令 update by ljf on 2020-08-07
|
|
|
|
|
if (Constant.WEB_FLAG) { |
|
|
|
|
log.info("not send code and close collection!"); |
|
|
|
|
num = 0; |
|
|
|
|
// 关闭连接
|
|
|
|
|
dataStr = null; |
|
|
|
|
ctx.close(); |
|
|
|
|
} else { |
|
|
|
|
Thread.sleep(200); |
|
|
|
|
// 继续发送下一个采集指令
|
|
|
|
|
SendOrderUtils.sendAllOrder2(deviceCodeParamList.get(num), ctx, port, IP, num, size); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
// 使用提取的方法发送下一个指令
|
|
|
|
|
whiteGatewaySendNextOrder(ctx, port, IP); |
|
|
|
|
} else if (dataStr.length() == 18) { |
|
|
|
|
// log.info("white gateway cloud receive message ===> " + dataStr);
|
|
|
|
|
log.info("白色网关冷量计接收===> " + dataStr); |
|
|
|
|
// 解析采集的报文,并保存到数据库
|
|
|
|
|
AnalysisReceiveOrder485 analysisReceiveOrder485 = new AnalysisReceiveOrder485(); //冷量机报文解析
|
|
|
|
|
analysisReceiveOrder485.analysisCloudOrder485(dataStr, deviceCodeParamList.get(num)); |
|
|
|
|
// 清空dataStr
|
|
|
|
|
dataStr = ""; |
|
|
|
|
// 判断发送的下标,如果不等于指令数组大小
|
|
|
|
|
num = num + 1; |
|
|
|
|
if (num > size - 1) { |
|
|
|
|
num = 0; |
|
|
|
|
Thread.sleep(200); |
|
|
|
|
// 继续发送下一个采集指令
|
|
|
|
|
SendOrderUtils.sendAllOrder2(deviceCodeParamList.get(num), ctx, port, IP, num, size); |
|
|
|
|
log.info("------一轮采集完成,继续下一轮--------"); |
|
|
|
|
} else { |
|
|
|
|
// 添加一个状态值,判断是否继续发送指令 update by ljf on 2020-08-07
|
|
|
|
|
if (Constant.WEB_FLAG) { |
|
|
|
|
log.info("not send code and close collection!"); |
|
|
|
|
num = 0; |
|
|
|
|
// 关闭连接
|
|
|
|
|
dataStr = null; |
|
|
|
|
ctx.close(); |
|
|
|
|
} else { |
|
|
|
|
Thread.sleep(200); |
|
|
|
|
// 继续发送下一个采集指令
|
|
|
|
|
SendOrderUtils.sendAllOrder2(deviceCodeParamList.get(num), ctx, port, IP, num, size); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
// 使用提取的方法发送下一个指令
|
|
|
|
|
whiteGatewaySendNextOrder(ctx, port, IP); |
|
|
|
|
} else { //if(dataStr.length() > 50)
|
|
|
|
|
// 清空dataStr
|
|
|
|
|
dataStr = null; |
|
|
|
|
// 判断发送的下标,如果不等于指令数组大小
|
|
|
|
|
num = num + 1; |
|
|
|
|
if (num > size - 1) { |
|
|
|
|
num = 0; |
|
|
|
|
Thread.sleep(200); |
|
|
|
|
// 继续发送下一个采集指令
|
|
|
|
|
SendOrderUtils.sendAllOrder2(deviceCodeParamList.get(num), ctx, port, IP, num, size); |
|
|
|
|
log.info("------一轮采集完成,继续下一轮--------"); |
|
|
|
|
} else { |
|
|
|
|
// 添加一个状态值,判断是否继续发送指令 update by ljf on 2020-08-07
|
|
|
|
|
if (Constant.WEB_FLAG) { |
|
|
|
|
num = 0; |
|
|
|
|
// 关闭连接
|
|
|
|
|
dataStr = null; |
|
|
|
|
ctx.close(); |
|
|
|
|
} else { |
|
|
|
|
Thread.sleep(200); |
|
|
|
|
// 继续发送下一个采集指令
|
|
|
|
|
SendOrderUtils.sendAllOrder2(deviceCodeParamList.get(num), ctx, port, IP, num, size); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
dataStr = ""; |
|
|
|
|
// 使用提取的方法发送下一个指令
|
|
|
|
|
whiteGatewaySendNextOrder(ctx, port, IP); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
@ -394,8 +370,7 @@ public class EchoServerHandler extends ChannelInboundHandlerAdapter {
|
|
|
|
|
// 异常捕捉
|
|
|
|
|
@Override |
|
|
|
|
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) { |
|
|
|
|
cause.getCause().printStackTrace(); |
|
|
|
|
log.info("异常捕捉,执行ctx.close" + cause.getCause()); |
|
|
|
|
log.error("异常捕捉,执行ctx.close, 网关端口:{}", port, cause); |
|
|
|
|
ctx.close(); // 关闭该Channel
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|