Newer
Older
CasicTimeGuard / src / main / java / com / casic / swing / ui / TimeGuardNtp.java
package com.casic.swing.ui;

import com.alibaba.fastjson.JSONException;
import com.alibaba.fastjson.JSONObject;
import com.casic.swing.utils.*;
import com.google.common.util.concurrent.ThreadFactoryBuilder;
import okhttp3.Request;

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.net.InetAddress;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

/**
 * @author a203
 */
public class TimeGuardNtp extends JFrame {
    private JPanel ntpPanel;
    private JLabel timeValueLabel;
    private JButton updateTimeButton;
    private JLabel currentTimeLabel;
    private JCheckBox autoCheckBox;
    private JComboBox<Integer> periodComboBox;
    private JLabel stateView;
    private JPanel dotPanel;
    private JTextField hostTextField;
    private JComboBox<String> localHostBox;
    private JTextField serverTextField;

    private final ScheduledExecutorService executorService = new ScheduledThreadPoolExecutor(
            1, new ThreadFactoryBuilder().setNameFormat("demo-pool-%d").build());
    private boolean hasNtp = false;

    public static void main(String[] args) {
        new TimeGuardNtp();
    }

    public TimeGuardNtp() {
        setContentPane(ntpPanel);
        setResizable(false);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        pack();
        setSize(400, 330);
        //居中
        setLocationRelativeTo(null);
        setVisible(true);
        stateView.setText("未同步");
        setStateView(Color.GRAY);

        StringHelper.createLogFile();

        /**
         * 时间间隔,单位为毫秒
         * */
        currentTimeLabel.setForeground(Color.BLUE);
        new Timer(1000, new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                String systemTime = TimeOrDateUtil.timestampToTime(System.currentTimeMillis());
                currentTimeLabel.setText(systemTime);
            }
        }).start();

        String assertsData = StringHelper.getAssertsData();
        if (!"".equals(assertsData)) {
            timeValueLabel.setText(assertsData);
        } else {
            timeValueLabel.setText("无法确定最近同步时间");
        }

        //初始化JComboBox
        for (Integer integer : Constant.PERIOD) {
            periodComboBox.addItem(integer);
        }
        java.util.List<InetAddress> addressList = HttpRequestHelper.localHost();
        for (InetAddress address : addressList) {
            localHostBox.addItem(address.getHostAddress());
        }

        //检查环境
//        new SwingWorker<Boolean, Void>() {
//
//            @Override
//            protected Boolean doInBackground() {
//                hasNtp = CommandUtil.checkEnv();
//                return hasNtp;
//            }
//
//            @Override
//            protected void done() {
//                if (!hasNtp) {
//                    JOptionPane.showMessageDialog(ntpPanel, "未当前设备发现可用的NTP配置", "Runtime Error", JOptionPane.ERROR_MESSAGE);
//                    //环境不对,关闭窗体
//                    dispose();
//                }
//                super.done();
//            }
//        }.execute();

        autoCheckBox.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                JCheckBox checkBox = (JCheckBox) e.getSource();
                if (checkBox.isSelected()) {
                    updateTimeButton.setEnabled(false);
                    periodComboBox.setEnabled(true);
                    hostTextField.setEnabled(false);
                    serverTextField.setEnabled(false);
                    startAutoSynchronize(Constant.PERIOD[0]);
                } else {
                    updateTimeButton.setEnabled(true);
                    periodComboBox.setEnabled(false);
                    hostTextField.setEnabled(true);
                    serverTextField.setEnabled(true);
                }
            }
        });

        periodComboBox.addItemListener(new ItemListener() {
            @Override
            public void itemStateChanged(ItemEvent e) {
                int period = (Integer) e.getItem();
                if (e.getStateChange() == ItemEvent.SELECTED) {
                    startAutoSynchronize(period);
                }
            }
        });

        //按钮点击事件
        updateTimeButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                updateView();
            }
        });
    }

    private void startAutoSynchronize(int period) {
        /**
         * 开启同步,只能开启一个同步线程
         *
         * scheduleAtFixedRate
         * 是以上一个任务开始的时间计时,period时间过去后,检测上一个任务是否执行完毕
         * 如果上一个任务执行完毕,则当前任务立即执行
         * 如果上一个任务没有执行完毕,则需要等上一个任务执行完毕后立即执行
         * */
        executorService.scheduleAtFixedRate(new Runnable() {
            @Override
            public void run() {
                updateView();
            }
        }, 0, period, TimeUnit.MINUTES);
    }

    private void updateView() {
        String host = hostTextField.getText().trim();
        if (host.isEmpty()) {
            autoCheckBox.setSelected(false);
            JOptionPane.showMessageDialog(ntpPanel, "授时中心服务器输入错误,请检查", "Runtime Error", JOptionPane.ERROR_MESSAGE);
            return;
        }
        String server = serverTextField.getText().trim();
        if (server.isEmpty()) {
            autoCheckBox.setSelected(false);
            JOptionPane.showMessageDialog(ntpPanel, "后台服务器地址输入错误,请检查", "Runtime Error", JOptionPane.ERROR_MESSAGE);
            return;
        }
//        String result = "5 Jan 11:20:24 ntpdate[807910]: adjust time server 114.118.7.161 offset -0.004064 sec";
//        String result = "5 Jan 11:24:06 ntpdate[824403]: no server suitable for synchronization found";
        String result = CommandUtil.ntpDate(host);
        System.out.println("命令执行结果 ===> " + result);

        if ("".equals(result)) {
            setStateView(Color.RED);
            stateView.setText("同步失败");
            timeValueLabel.setText("");
        } else {
            String systemTime = TimeOrDateUtil.timestampToTime(System.currentTimeMillis());

            String resultString = result.split(":")[3];
            boolean isSuccess = !resultString.contains("no server suitable");
            if (isSuccess) {
                setStateView(Color.GREEN);
                stateView.setText("同步成功");
                timeValueLabel.setText(systemTime);
                //同步成功之后将时间存入本地
                StringHelper.saveAssertsData(systemTime);
            } else {
                setStateView(Color.RED);
                stateView.setText("同步失败");
                timeValueLabel.setText("");
            }
            //POST提交
            JSONObject object = new JSONObject();
            try {
                object.put("deviceIp", localHostBox.getSelectedItem());
                object.put("ntpResult", result);

                String[] dataSplit = resultString.split(" ");
                object.put("deltaTime", dataSplit[6]);
                object.put("createTime", systemTime);
                if (autoCheckBox.isSelected()) {
                    object.put("frequency", periodComboBox.getSelectedItem());
                } else {
                    object.put("frequency", "");
                }
            } catch (JSONException e) {
                e.printStackTrace();
            }
            Request request = new Request.Builder()
                    .url("http://" + server + "/ntp/saveResult")
                    .post(HttpRequestHelper.createRequestBody(object.toJSONString()))
                    .build();
            HttpRequestHelper.doPost(request, new IHttpCallback() {

                @Override
                public void onSuccess(String s) {

                }

                @Override
                public void onFailure(Exception e) {
                    e.printStackTrace();
                }
            });
        }
    }

    private void setStateView(Color color) {
        dotPanel.setPreferredSize(new Dimension(15, 15));
        dotPanel.setBackground(color);
    }
}