package com.zy.core.network; import com.zy.asrs.entity.DeviceConfig; import com.zy.common.utils.RedisUtil; import com.zy.core.ThreadHandler; import com.zy.core.enums.RedisKeyType; import com.zy.core.model.CommandResponse; import com.zy.core.model.command.StationCommand; import com.zy.core.network.api.ZyStationConnectApi; import com.zy.core.network.entity.ZyStationStatusEntity; import java.util.List; import com.zy.core.network.fake.ZyStationFakeConnect; import com.zy.core.network.fake.ZyStationFakeSegConnect; import com.zy.core.network.fake.ZyStationV4FakeSegConnect; import com.zy.core.network.real.ZyStationRealConnect; import com.zy.core.network.real.ZyStationV3RealConnect; import com.zy.core.network.real.ZyStationV4RealConnect; import lombok.extern.slf4j.Slf4j; import java.util.Collections; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.ThreadFactory; import java.util.concurrent.TimeUnit; /** * 输送站连接驱动 */ @Slf4j public class ZyStationConnectDriver implements ThreadHandler { private static final ZyStationFakeConnect zyStationFakeConnect = new ZyStationFakeConnect(); private static final ZyStationFakeSegConnect zyStationFakeSegConnect = new ZyStationFakeSegConnect(); private static final ZyStationV4FakeSegConnect zyStationV4FakeSegConnect = new ZyStationV4FakeSegConnect(); private volatile boolean connected = false; private volatile boolean connecting = false; private DeviceConfig deviceConfig; private RedisUtil redisUtil; private volatile ZyStationConnectApi zyStationConnectApi; private volatile boolean closed = false; private ScheduledExecutorService executor; private final Object connectLock = new Object(); public ZyStationConnectDriver(DeviceConfig deviceConfig, RedisUtil redisUtil) { this.deviceConfig = deviceConfig; this.redisUtil = redisUtil; } @Override public void run() { } @Override public boolean connect() { synchronized (connectLock) { if (closed) { return false; } if (connected && zyStationConnectApi != null) { return true; } connecting = true; try { ZyStationConnectApi connectApi; if (deviceConfig.getFake() == 0) { if ("ZyStationV3Thread".equals(deviceConfig.getThreadImpl())) { connectApi = new ZyStationV3RealConnect(deviceConfig, redisUtil); } else if ("ZyStationV4Thread".equals(deviceConfig.getThreadImpl())) { connectApi = new ZyStationV4RealConnect(deviceConfig, redisUtil); } else { connectApi = new ZyStationRealConnect(deviceConfig, redisUtil); } } else { if ("ZyStationV3Thread".equals(deviceConfig.getThreadImpl())) { zyStationFakeSegConnect.addFakeConnect(deviceConfig, redisUtil); connectApi = zyStationFakeSegConnect; } else if ("ZyStationV4Thread".equals(deviceConfig.getThreadImpl())) { zyStationV4FakeSegConnect.addFakeConnect(deviceConfig, redisUtil); connectApi = zyStationV4FakeSegConnect; } else { zyStationFakeConnect.addFakeConnect(deviceConfig, redisUtil); connectApi = zyStationFakeConnect; } } boolean connect = connectApi.connect(); connected = connect; if (connect) { zyStationConnectApi = connectApi; } else { zyStationConnectApi = null; } return connect; } finally { connecting = false; } } } @Override public void close() { closed = true; ScheduledExecutorService ex = executor; if (ex != null) { try { ex.shutdownNow(); } catch (Exception ignore) {} } ZyStationConnectApi connectApi = zyStationConnectApi; if (connectApi != null) { connectApi.disconnect(); zyStationConnectApi = null; } connected = false; connecting = false; } public void start() { executor = Executors.newSingleThreadScheduledExecutor(new ThreadFactory() { @Override public Thread newThread(Runnable r) { Thread t = new Thread(r); t.setName("DevpConnect-" + deviceConfig.getDeviceNo()); t.setDaemon(true); return t; } }); executor.scheduleAtFixedRate(() -> { if (closed || Thread.currentThread().isInterrupted()) { return; } try { if (!connected) { connect(); } } catch (Exception e) { e.printStackTrace(); } }, 0, 1000, TimeUnit.MILLISECONDS); } public List getStatus() { ZyStationConnectApi connectApi = zyStationConnectApi; if (!connected || connecting || connectApi == null) { return Collections.emptyList(); } return connectApi.getStatus(deviceConfig.getDeviceNo()); } public CommandResponse sendCommand(StationCommand command) { ZyStationConnectApi connectApi = zyStationConnectApi; if (!connected || connecting || connectApi == null) { return new CommandResponse(false, "设备未连接,命令下发失败"); } while (true) { Object lock = redisUtil.get(RedisKeyType.STATION_EXECUTE_COMMAND_LOCK.key); if(lock != null) { try { Thread.sleep(500); }catch (Exception e) { e.printStackTrace(); } }else { redisUtil.set(RedisKeyType.STATION_EXECUTE_COMMAND_LOCK.key, "lock", 60 * 5); break; } } CommandResponse commandResponse = connectApi.sendCommand(deviceConfig.getDeviceNo(), command); redisUtil.del(RedisKeyType.STATION_EXECUTE_COMMAND_LOCK.key); return commandResponse; } public CommandResponse sendOriginCommand(String address, short[] data) { ZyStationConnectApi connectApi = zyStationConnectApi; if (!connected || connecting || connectApi == null) { return new CommandResponse(false, "设备未连接,原始命令下发失败"); } return connectApi.sendOriginCommand(address, data); } public byte[] readOriginCommand(String address, int length) { ZyStationConnectApi connectApi = zyStationConnectApi; if (!connected || connecting || connectApi == null) { return new byte[0]; } return connectApi.readOriginCommand(address, length); } }