ClientApp.java 5.08 KB
package com.bsth.client;

import com.bsth.client.pd.codec.PdMessageCodecFactory;
import com.bsth.client.pd.handler.PdClientHandler;
import com.bsth.client.pd.protocol.Pd_31_0;
import com.bsth.util.ConfigUtil;
import org.apache.mina.core.future.ConnectFuture;
import org.apache.mina.core.future.WriteFuture;
import org.apache.mina.core.session.IdleStatus;
import org.apache.mina.core.session.IoSession;
import org.apache.mina.core.session.IoSessionConfig;
import org.apache.mina.filter.codec.ProtocolCodecFilter;
import org.apache.mina.filter.logging.LogLevel;
import org.apache.mina.filter.logging.LoggingFilter;
import org.apache.mina.transport.socket.nio.NioSocketConnector;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.net.InetSocketAddress;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;


@Component
public class ClientApp {

    private static NioSocketConnector pdDataConnector;

    @Autowired
    private PdClientHandler pdClient;
    @Autowired
    GpsDataBuffer gpsBeforeBuffer;

    static Logger logger = LoggerFactory.getLogger(ClientApp.class);
    private static ExecutorService exec;

    private ScheduledExecutorService sexec;

    public static boolean dconnect(String device) {
        boolean flag = false;
        try {
            ConnectFuture con = pdDataConnector.connect(new InetSocketAddress(ConfigUtil.get("gps.server.pd"), Integer.parseInt(ConfigUtil.get("gps.port.pd"))));
            con.awaitUninterruptibly();
            IoSession session = con.getSession();
            session.setAttribute("deviceId", device);
            com.bsth.client.pd.protocol.PdMessage msg = new com.bsth.client.pd.protocol.PdMessage();
            Pd_31_0 body = new Pd_31_0();
            body.setFunCode((short)0x15);
            body.setLineId(0);
            body.setDeviceId(device);
            msg.setMessageBody(body);
            msg.setVersion((short)1);
            msg.setSerialNo((short)1);
            msg.setCommandType((short)0x31);
            byte[] bytes = msg.write();
            WriteFuture write = session.write(bytes);
            write.awaitUninterruptibly();
            flag = true;

            logger.info("dconnect...");
            pdSession = session;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return flag;
    }

    public static void pdconnect(final String device) {
        exec.submit(() -> {
            // TODO Auto-generated method stub
            long now = System.currentTimeMillis();
            boolean flag = false;
            while (!flag) {
                flag = dconnect(device);
            }
            System.out.println("设备编号:" + device + "重连, cost time: " + (System.currentTimeMillis() - now));
        });
    }

    public static void pdreconn(){
        pdconnect(ConfigUtil.get("forward.device.name"));
    }

    public void destroy(){
        try {
            logger.warn("socket client destroy!!!");
            exec.shutdownNow();
            sexec.shutdownNow();

            pdDataConnector.dispose(true);
        } catch (Exception e) {
            logger.error("", e);
        }
    }

    public void init() {
        logger.warn("socket client init...");
        exec = Executors.newFixedThreadPool(3);
        sexec = Executors.newSingleThreadScheduledExecutor(r -> {
            // TODO Auto-generated method stub
            Thread t = new Thread(r);
            t.setName("SessionCheckExecutor");
            return t;
        });
        sexec.scheduleAtFixedRate(new SessionChecker(), 20, 20, TimeUnit.SECONDS);
        /*******************************浦东********************************/
        pdDataConnector = new NioSocketConnector();

        LoggingFilter log = new LoggingFilter();
        log.setMessageReceivedLogLevel(LogLevel.DEBUG);
        pdDataConnector.getFilterChain().addLast("logger", log);

        pdDataConnector.getFilterChain().addLast("codec",
                new ProtocolCodecFilter(new PdMessageCodecFactory()));

        IoSessionConfig config = pdDataConnector.getSessionConfig();

        config.setReadBufferSize(4096);
        config.setWriteTimeout(10000);
        config.setWriterIdleTime(60000);

        config.setIdleTime(IdleStatus.BOTH_IDLE, 60);

        pdDataConnector.setHandler(pdClient);

        pdconnect(ConfigUtil.get("forward.device.name"));
    }


    static IoSession pdSession;

    final class SessionChecker implements Runnable {

        @Override
        public void run() {
            try {

                if(!pdSession.isActive()){
                    logger.warn("浦东网关注销");
                    ClientApp.pdreconn();
                }
            } catch (Exception e) {
                logger.error("SessionChecker异常", e);
            }
        }
    }
}