package com.warewms.hailiang.connect; import cn.hutool.extra.spring.SpringUtil; import com.github.rholder.retry.*; import com.warewms.hailiang.config.CodeReadProperties; import com.warewms.hailiang.connect.base.TCPConnectBase; import com.warewms.hailiang.domain.Device; import com.warewms.hailiang.domain.DeviceLog; import com.warewms.hailiang.domain.RetroactiveNow; import com.warewms.hailiang.service.RetroactiveNowService; import io.netty.bootstrap.Bootstrap; import io.netty.buffer.ByteBuf; import io.netty.buffer.Unpooled; import io.netty.channel.*; import io.netty.channel.nio.NioEventLoopGroup; import io.netty.channel.socket.SocketChannel; import io.netty.channel.socket.nio.NioSocketChannel; import io.netty.handler.timeout.IdleStateHandler; import io.netty.util.CharsetUtil; import lombok.extern.slf4j.Slf4j; import java.util.concurrent.*; import java.util.concurrent.atomic.AtomicBoolean; /** * Created with IntelliJ IDEA. * * @author: liuzhifei * Date: 2023/8/9 * Time: 15:45 * To change this template use File | Settings | File Templates. * Description:退火读码器连接 **/ @Slf4j public class CodeReader14Connect implements TCPConnectBase { private final String IP_ADDR = "172.20.27.14"; private final int PORT = 51236; private final String deviceName = "CodeReader14"; private boolean enable = true; private ChannelFuture future; private Bootstrap bootstrap; private EventLoopGroup group; private ChannelPipeline pipeline; private RetroactiveNowService retroactiveNowService; private ScheduledFuture scheduledFuture = null; private ScheduledExecutorService scheduledExecutorService; { retroactiveNowService = SpringUtil.getBean(RetroactiveNowService.class); scheduledExecutorService = SpringUtil.getBean(ScheduledExecutorService.class); } @Override public void init() throws InterruptedException { if (enable) { log.info("ip:{},deviceName:{}正在进行连接", IP_ADDR, deviceName); group = new NioEventLoopGroup(); try { bootstrap = new Bootstrap(); bootstrap.group(group).channel(NioSocketChannel.class) .option(ChannelOption.TCP_NODELAY, true) .handler(new ChannelInitializer() { @Override protected void initChannel(SocketChannel socketChannel) throws Exception { pipeline = socketChannel.pipeline(); pipeline.addLast(new IdleStateHandler(1, 0, 0, TimeUnit.SECONDS)); pipeline.addLast(new ChannelInboundHandlerAdapter() { @Override public void channelInactive(ChannelHandlerContext ctx) { SpringUtil.getApplicationContext().publishEvent(new Device(deviceName, "2")); log.error("设备:{}连接已断开!", deviceName); scheduledFuture.cancel(true); retry(); } @Override public void channelRead(ChannelHandlerContext ctx, Object msg) { ByteBuf byteBuf = (ByteBuf) msg; processMessages(String.valueOf(byteBuf.toString(CharsetUtil.UTF_8))); } }); } }); future = bootstrap.connect(IP_ADDR, PORT).sync(); future.addListener((channelFuture) -> { if (channelFuture.isSuccess()) { SpringUtil.getApplicationContext().publishEvent(new Device(deviceName, "1")); log.info("ip:{},deviceName:{}连接成功", IP_ADDR, deviceName); ConnectsTheHeartbeat(); } else { log.info("ip:{},deviceName:{}连接失败等待重试!", IP_ADDR, deviceName); retry(); } }); } catch (Exception e) { log.error("ip:{},deviceName:{}连接异常,{},准备重试", IP_ADDR, deviceName, e.getMessage()); retry(); } } } @Override public void retry() { Retryer retryer = RetryerBuilder.newBuilder() .retryIfResult(Boolean.FALSE::equals) .retryIfExceptionOfType(Exception.class) .withStopStrategy(StopStrategies.neverStop()) .withWaitStrategy(WaitStrategies.fixedWait(5, TimeUnit.SECONDS)) .build(); try { retryer.call(new Callable() { AtomicBoolean isSuccess = new AtomicBoolean(false); @Override public Boolean call() throws Exception { log.info("ip:{},deviceName:{}连接重试", IP_ADDR, deviceName); future = bootstrap.connect(IP_ADDR, PORT).sync(); future.addListener((channelFuture) -> { isSuccess.set(channelFuture.isSuccess()); if (channelFuture.isSuccess()) { SpringUtil.getApplicationContext().publishEvent(new Device(deviceName, "1")); log.info("ip:{},deviceName:{}连接成功", IP_ADDR, deviceName); ConnectsTheHeartbeat(); } else { log.info("ip:{},deviceName:{}连接失败等待重试!", IP_ADDR, deviceName); } }); Thread.sleep(3000); return isSuccess.get(); } }); } catch (RetryException | ExecutionException e) { e.printStackTrace(); } } /** * 连接心跳 */ private void ConnectsTheHeartbeat() { scheduledFuture = scheduledExecutorService.scheduleWithFixedDelay(() -> { try { // log.info("发送心跳,设备:{}", deviceName); pipeline.writeAndFlush(Unpooled.copiedBuffer(CodeReadProperties.heartbeat, CharsetUtil.UTF_8)); } catch (Exception e) { log.error("设备:{},连接中断", deviceName); SpringUtil.getApplicationContext().publishEvent(new Device(deviceName, "2")); retry(); } }, 0, 3, TimeUnit.SECONDS); } @Override public void close() { group.shutdownGracefully(); } @Override public String getDeviceName() { return deviceName; } @Override public ChannelPipeline getChannel() { return pipeline; } @Override public void processMessages(String message) { try { log.info("退货下料读码器消息:{}", message); if (CodeReadProperties.failureReturnInstruction.equals(message)) { SpringUtil.getApplicationContext().publishEvent(new DeviceLog("Z1_TuiHuoXiaLiao_DMQ-1-27.14", deviceName, "未识别到码", "2")); } else { // 读取到批次号保存到数据库中 RetroactiveNow retroactiveNow = new RetroactiveNow(); retroactiveNow.setLotNo(message); retroactiveNow.setStatus("7"); retroactiveNow.setDeviceId("Z1_TuiHuoXiaLiao_DMQ-1-27.14"); retroactiveNowService.finishProduce(retroactiveNow); //添加设备日志 SpringUtil.getApplicationContext().publishEvent(new DeviceLog("Z1_TuiHuoXiaLiao_DMQ-1-27.14", deviceName, "识别到码:" + message, "1")); } Thread.sleep(500); }catch (Exception e){ log.error("退货下料读码任务执行异常,msg:",e); SpringUtil.getApplicationContext().publishEvent(new DeviceLog("Z1_TuiHuoXiaLiao_DMQ-1-27.14", deviceName, "读码任务出错,msg:"+e.getMessage(), "2")); } } // private int a = 1; // // @Override // public void processMessages(String message) { // try { // if (CodeReadProperties.failureReturnInstruction.equals(message)) { // SpringUtil.getApplicationContext().publishEvent(new DeviceLog("Z1_TuiHuoXiaLiao_DMQ-1-27.14", deviceName, "未识别到码", "2")); // return; // } // SpringUtil.getApplicationContext().publishEvent(new DeviceLog("Z1_TuiHuoXiaLiao_DMQ-1-27.14", deviceName, "识别到码:" + message, "1")); // Thread.sleep(500); // if (a <= 300) { // a++; // pipeline.writeAndFlush(Unpooled.copiedBuffer(CodeReadProperties.startTheCommand, CharsetUtil.UTF_8)); // } // } catch (Exception e) { // e.printStackTrace(); // SpringUtil.getApplicationContext().publishEvent(new DeviceLog("Z1_TuiHuoXiaLiao_DMQ-1-27.14", deviceName, "读码任务出错,msg:" + e.getMessage(), "2")); // } // } }