• jbase仪器接口设计


    jbase的计划有借助虚拟M来实现连仪器,之前陆续写了些TCP逻辑,今天终于整理完成了仪器设计。首先用java的cs程序测试TCP的服务和客户端

    javafx的示例加强

    package sample;
    
    import javafx.application.Application;
    import javafx.event.EventHandler;
    import javafx.fxml.FXMLLoader;
    import javafx.geometry.Pos;
    import javafx.scene.Parent;
    import javafx.scene.Scene;
    import javafx.scene.control.Label;
    import javafx.scene.input.MouseEvent;
    import javafx.scene.layout.FlowPane;
    import javafx.scene.layout.VBox;
    import javafx.stage.Stage;
    import javafx.scene.control.Button;
    import javafx.scene.control.TextArea;
    import javafx.scene.control.ScrollPane;
    
    import java.awt.*;
    import java.io.*;
    import java.net.ServerSocket;
    import java.net.Socket;
    import java.util.Timer;
    import java.util.TimerTask;
    import java.util.concurrent.atomic.AtomicInteger;
    
    public class Main extends Application {
    
        //数字
        static int num = 0;
    
        //场景
        Scene scene;
    
        //场景1
        Scene scene1;
    
        //定时发送
        Socket sendSocket = null;
    
        //自动发送次数
        int sendNum = 0;
    
        //通讯日志
        StringBuilder sbLog=new StringBuilder();
    
        //换行符
        String lineStr=System.getProperty("line.separator");
    
    
        @Override
        public void start(Stage stage) throws Exception {
            //舞台标题
            stage.setTitle("第一个java程序");
            // 流式布局:按照控件的添加次序按个摆放,按照从上到下、从左到右的次序摆放。
            FlowPane pane = new FlowPane(5, 5);
            // 居中显示
            pane.setAlignment(Pos.CENTER);
            // 场景
            scene = new Scene(pane, 800, 600);
    
    
            // 标签
            Label label = new Label("初始值:" + num);
    
    
            // 加1按钮
            Button addButton = new Button("加1");
            addButton.setOnMouseClicked(e -> {
                num++;
                label.setText("当前值:" + num);
            });
    
            //减1按钮
            Button subButton = new Button("减1");
            subButton.setOnMouseClicked(e -> {
                num--;
                label.setText("当前值:" + num);
            });
    
            //切换到场景1
            Button btnScene1 = new Button("场景1");
            btnScene1.setOnMouseClicked(e -> {
                stage.setScene(scene1);
            });
    
            //弹出一个子窗口
            Button btnShowChildForm = new Button("子窗口");
            btnShowChildForm.setOnMouseClicked(e -> {
                Child.ShowChild("子窗口", "传给子窗口的参数");
            });
    
            // 创建一个TextArea控件
            TextArea textArea = new TextArea();
            textArea.setWrapText(true); // 设置文本自动换行
    
            //定时器,主动上传时候用
            Timer timer = new Timer();
            TimerTask task = new TimerTask() {
                @Override
                public void run() {
                    if (sendSocket != null) {
                        try {
                            sendNum++;
                            // 发送请求消息到服务端
                            OutputStream outputStream = sendSocket.getOutputStream();
                            PrintWriter out = new PrintWriter(new OutputStreamWriter(outputStream, "GBK"), true);
                            out.println("这是定时发送的第" + sendNum + "次数据");
                            out.flush();
                        } catch (Exception ex) {
    
                        }
                    }
                }
            };
            // 设置定时器的执行策略,延迟0秒后开始执行,每隔1秒执行一次
            timer.schedule(task, 0, 5000);
    
    
            //启动tcp服务
            Button btnTcpServer = new Button("TCP服务");
            btnTcpServer.setOnMouseClicked(e -> {
                Thread clientThread = new Thread(new Runnable() {
                    @Override
                    public void run() {
                        try {
                            ServerSocket serverSocket = new ServerSocket(8888);
                            //增加一个无限循环
                            while (true) {
                                sbLog.append("服务启动"+lineStr);
                                System.out.println("服务启动");
                                //通知界面
                                javafx.application.Platform.runLater(()->{
                                    textArea.setText(sbLog.toString());
                                });
                                //等待客户端连接,阻塞
                                Socket clientSocket = serverSocket.accept();
                                sendSocket = clientSocket;
                                //得到输出流
                                PrintWriter out = new PrintWriter(clientSocket.getOutputStream(), true);
                                System.out.println("客户端连接");
                                sbLog.append("客户端连接"+lineStr);
                                //通知界面
                                javafx.application.Platform.runLater(()->{
                                    textArea.setText(sbLog.toString());
                                });
                                //得到输入流
                                InputStream inputStream = clientSocket.getInputStream();
                                //IO读取
                                byte[] buf = new byte[10240];
                                int readlen = 0;
                                //阻塞读取数据
                                while ((readlen = inputStream.read(buf)) != -1) {
                                    System.out.println(new String(buf, 0, readlen, "GBK"));
                                    sbLog.append(new String(buf, 0, readlen, "GBK")+lineStr);
                                    //通知界面
                                    javafx.application.Platform.runLater(()->{
                                        textArea.setText(sbLog.toString());
                                    });
                                }
                                //关闭输入
                                inputStream.close();
                                //关闭输出
                                out.close();
                                clientSocket.close();
                            }
                        } catch (Exception e) {
    
                        }
                    }
                });
                clientThread.start();
            });
    
            //启动tcp客户端
            Button btnTcpClient = new Button("TCP客户端");
            btnTcpClient.setOnMouseClicked(e -> {
                Thread clientThread = new Thread(new Runnable() {
                    @Override
                    public void run() {
                        try {
                            try {
                                // 创建 Socket 对象并连接到服务端
                                Socket socket = new Socket("172.16.1.232", 1991);
                                sendSocket = socket;
                                // 发送请求消息到服务端
                                OutputStream outputStream = socket.getOutputStream();
                                PrintWriter out = new PrintWriter(new OutputStreamWriter(outputStream, "GBK"), true);
                                out.println("你好,我是客户端");
                                out.flush();
                                //得到输入流
                                InputStream inputStream = socket.getInputStream();
                                //IO读取
                                byte[] buf = new byte[10240];
                                int readlen = 0;
                                //阻塞读取数据
                                while ((readlen = inputStream.read(buf)) != -1) {
                                    System.out.println(new String(buf, 0, readlen, "GBK"));
                                    sbLog.append(new String(buf, 0, readlen, "GBK")+lineStr);
                                    out.println("我已经收到数据");
                                    //通知界面
                                    javafx.application.Platform.runLater(()->{
                                        textArea.setText(sbLog.toString());
                                    });
                                }
                                //关闭输入
                                inputStream.close();
                                //关闭输出
                                out.close();
                                // 关闭连接
                                socket.close();
                            } catch (IOException ex) {
                                ex.printStackTrace();
                            }
                        } catch (Exception e) {
    
                        }
                    }
                });
                clientThread.start();
            });
    
            pane.getChildren().addAll(addButton, subButton, btnScene1, btnShowChildForm, label, textArea, btnTcpServer, btnTcpClient);
    
    
            // 场景1
            // 流式布局:按照控件的添加次序按个摆放,按照从上到下、从左到右的次序摆放。
            FlowPane pane1 = new FlowPane(10, 10);
            // 居中显示
            pane1.setAlignment(Pos.CENTER);
            scene1 = new Scene(pane1, 200, 150);
    
            //返回开始的场景
            Button btnReturn = new Button("返回");
            btnReturn.setOnMouseClicked(e -> {
                stage.setScene(scene);
            });
            pane1.getChildren().addAll(btnReturn);
    
            //默认场景和显示
            stage.setScene(scene);
            stage.show();
        }
    
    
        public static void main(String[] args) {
            launch(args);
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127
    • 128
    • 129
    • 130
    • 131
    • 132
    • 133
    • 134
    • 135
    • 136
    • 137
    • 138
    • 139
    • 140
    • 141
    • 142
    • 143
    • 144
    • 145
    • 146
    • 147
    • 148
    • 149
    • 150
    • 151
    • 152
    • 153
    • 154
    • 155
    • 156
    • 157
    • 158
    • 159
    • 160
    • 161
    • 162
    • 163
    • 164
    • 165
    • 166
    • 167
    • 168
    • 169
    • 170
    • 171
    • 172
    • 173
    • 174
    • 175
    • 176
    • 177
    • 178
    • 179
    • 180
    • 181
    • 182
    • 183
    • 184
    • 185
    • 186
    • 187
    • 188
    • 189
    • 190
    • 191
    • 192
    • 193
    • 194
    • 195
    • 196
    • 197
    • 198
    • 199
    • 200
    • 201
    • 202
    • 203
    • 204
    • 205
    • 206
    • 207
    • 208
    • 209
    • 210
    • 211
    • 212
    • 213
    • 214
    • 215
    • 216
    • 217
    • 218
    • 219
    • 220
    • 221
    • 222
    • 223
    • 224
    • 225
    • 226
    • 227
    • 228
    • 229
    • 230
    • 231
    • 232
    • 233
    • 234
    • 235
    • 236
    • 237
    • 238
    • 239
    • 240
    • 241
    • 242
    • 243
    • 244
    • 245
    • 246
    • 247
    • 248
    • 249

    在这里插入图片描述

    客户端测试成功后设计jbase仪器基础,这里首先要理解连设备的本质,连TCP设备的话,其实真正的业务只关心我当做客户端还是服务端、以什么编码、然后解析和发送数据,我并不想关系TCP的实现细节。所以可以把初始化TCP和处理数据及定时上传以接口形式抽取出来。

    先抽取处理仪器数据接口IMachDealData,具体仪器只需要实现该接口即可,抽取变性很重要

    package LIS.Core.Socket;
    
    import java.io.PrintWriter;
    import java.net.Socket;
    
    /**
     * 仪器处理数据接口,具体的仪器接口实现此接口后初始化MachSocketBase对象
     */
    public interface IMachDealData {
        /**
         * 处理上传定时器接口
         * @param sender Socket对象,用来发送比特用
         * @param writer 用来发布初始化指定的字符用
         */
        public void DealUpTimer(Socket sender, PrintWriter writer);
    
        /**
         * 处理数据接收
         * @param data 公共层处理成字符串的数据
         * @param buf 没处理的比特数组
         * @param sender Socket对象,用来发送比特用
         * @param writer 用来发布初始化指定的字符用
         */
        public void DealReceive(String data, byte[] buf, Socket sender, PrintWriter writer);
    
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27

    然后实现MachSocketBase类作为连接TCP仪器的基础类,里面实现了tcp的客户端和服务端和定时器,里面对数据处理都是调用接口操作

    package LIS.Core.Socket;
    
    import java.io.*;
    import java.net.ServerSocket;
    import java.net.Socket;
    import java.util.ArrayList;
    import java.util.List;
    import java.util.Timer;
    import java.util.TimerTask;
    
    import LIS.Core.Socket.IMachDealData;
    import LIS.Core.Util.LogUtils;
    
    /**
     * 通过Socket连接的仪器操作基类,由该类提供TCP客户端和服务端的公共逻辑,并且调用处理数据接口处理数据,从而分离TCP主体和业务处理逻辑,达到简化连设备目的
     */
    public class MachSocketBase {
        /**
         * 发送数据的操作对象
         */
        public Socket Sender = null;
    
        /**
         * 写操作对象
         */
        public PrintWriter Writer = null;
    
        /**
         * 主动上传定时器
         */
        public Timer UpTimer = null;
    
        /**
         * 处理接口对象
         */
        public IMachDealData DealObj;
    
        /**
         * 编码
         */
        public String Encode;
    
        /**
         * 要关闭的客户端端口
         */
        private Socket closeSocket = null;
    
        /**
         * 要关闭的服务端口
         */
        private ServerSocket closeServerSocket = null;
    
        /**
         * 存IP和端口的唯一标识串
         */
        public String ID;
    
        /**
         * 处理类的全面
         */
        public String DealClassName;
    
        /**
         * 主处理进程
         */
        Thread MainThread = null;
    
        /**
         * 定时器任务
         */
        TimerTask timerTask = null;
    
        /**
         * 上传间隔
         */
        Long UpPeriod = null;
    
        /**
         * 存启动和停止的错误串
         */
        public String Err="";
    
        /**
         * 停止负载
         *
         * @return 有错误就返回错误
         */
        public String Stop() {
            try {
                if (MainThread != null) {
                    MainThread.interrupt();
                }
                if (UpTimer != null) {
                    UpTimer.cancel();
                }
                if (closeSocket != null) {
                    closeSocket.close();
                    ;
                }
                if (closeServerSocket != null) {
                    closeServerSocket.close();
                    ;
                }
            } catch (Exception ex) {
                Err=ex.getCause().getMessage();
                LogUtils.WriteExceptionLog("停止仪器TCP异常", ex);
                return ex.getCause().getMessage();
            }
            return "";
        }
    
    
        /**
         * 启动连接和定时器
         * @return 有错误就返回错误
         */
        public String Start() {
            try {
                if (UpTimer != null) {
                    // 设置定时器的执行策略,延迟0秒后开始执行,每隔1秒执行一次
                    UpTimer.schedule(timerTask, 0, UpPeriod);
                }
                if (MainThread != null) {
                    MainThread.start();
                }
            } catch (Exception ex) {
                Err=ex.getCause().getMessage();
                LogUtils.WriteExceptionLog("启动仪器TCP异常", ex);
                return ex.getCause().getMessage();
            }
            return "";
    
        }
    
    
        /**
         * 构造一个Socket基础并且启动Socket
         *
         * @param ip       IP地址,当服务端传空串
         * @param port     端口
         * @param upPeriod 上传毫秒间隔,不是主动上传的传null
         * @param dealObj  处理接口实现类
         * @param encode   编码格式,传null或空串默认为GBK
         */
        public MachSocketBase(String ip, int port, Long upPeriod, IMachDealData dealObj, String encode) {
            //处理对象
            DealObj = dealObj;
            //编码
            if (encode == null || encode.isEmpty()) {
                encode = "GBK";
            }
            Encode = encode;
            UpPeriod = upPeriod;
            ID = ip + ":" + port;
            if(dealObj!=null)
            {
                DealClassName=dealObj.getClass().getName();
            }
            //上传定时器
            if (upPeriod != null) {
                UpTimer = new Timer();
                timerTask = new TimerTask() {
                    @Override
                    public void run() {
                        try {
                            //初始化写对象
                            if (Sender != null && Writer == null) {
                                Writer = new PrintWriter(new OutputStreamWriter(Sender.getOutputStream(), Encode), false);
                            }
                            DealObj.DealUpTimer(Sender, Writer);
                        } catch (Exception ex) {
                            LogUtils.WriteExceptionLog("仪器上传定时器异常", ex);
                        }
                    }
                };
    
            }
            //当客户端
            if (!ip.isEmpty()) {
                MainThread = new Thread(new Runnable() {
                    @Override
                    public void run() {
                        //得到输入流
                        InputStream inputStream = null;
                        //创建Socket对象并连接到服务端
                        Socket socket = null;
                        try {
                            //创建Socket对象并连接到服务端
                            socket = new Socket(ip, port);
                            Sender = socket;
                            closeSocket = socket;
                            Writer = new PrintWriter(new OutputStreamWriter(Sender.getOutputStream(), Encode), false);
                            //得到输入流
                            inputStream = socket.getInputStream();
                            //IO读取
                            byte[] buf = new byte[102400];
                            int readlen = 0;
                            //阻塞读取数据
                            while ((readlen = inputStream.read(buf)) != -1) {
                                String res = new String(buf, 0, readlen, Encode);
                                byte[] targetArray = new byte[readlen];
                                System.arraycopy(buf, 0, targetArray, 0, readlen);
                                //处理接收数据
                                DealObj.DealReceive(res, targetArray, Sender, Writer);
                            }
                        } catch (IOException ex) {
                            LogUtils.WriteExceptionLog("侦听仪器TCP异常", ex);
                        } finally {
                            try {
                                if (inputStream != null) {
                                    //关闭输入
                                    inputStream.close();
                                }
                                if (Writer != null) {
                                    Writer.flush();
                                    //关闭输出
                                    Writer.close();
                                }
                                if (socket != null) {
                                    // 关闭连接
                                    socket.close();
                                }
                            } catch (Exception ex) {
                                LogUtils.WriteExceptionLog("释放TCP资源异常", ex);
                            }
    
                        }
                    }
                });
    
            }
            //当服务端
            else {
                MainThread = new Thread(new Runnable() {
                    @Override
                    public void run() {
                        //得到输入流
                        InputStream inputStream = null;
                        //创建Socket对象并连接到服务端
                        Socket socket = null;
                        try {
                            ServerSocket serverSocket = new ServerSocket(port);
                            closeServerSocket = serverSocket;
                            //增加一个无限循环
                            while (true) {
                                //等待客户端连接,阻塞
                                socket = serverSocket.accept();
                                Sender = socket;
                                //得到输出流
                                Writer = new PrintWriter(new OutputStreamWriter(Sender.getOutputStream(), Encode), false);
                                //得到输入流
                                inputStream = socket.getInputStream();
                                //IO读取
                                byte[] buf = new byte[102400];
                                int readlen = 0;
                                //阻塞读取数据
                                while ((readlen = inputStream.read(buf)) != -1) {
                                    String res = new String(buf, 0, readlen, Encode);
                                    byte[] targetArray = new byte[readlen];
                                    System.arraycopy(buf, 0, targetArray, 0, readlen);
                                    //处理接收数据
                                    DealObj.DealReceive(res, targetArray, Sender, Writer);
                                }
                            }
                        } catch (IOException ex) {
                            LogUtils.WriteExceptionLog("侦听仪器TCP异常", ex);
                        } finally {
                            try {
                                if (inputStream != null) {
                                    //关闭输入
                                    inputStream.close();
                                }
                                if (Writer != null) {
                                    Writer.flush();
                                    //关闭输出
                                    Writer.close();
                                }
                                if (socket != null) {
                                    // 关闭连接
                                    socket.close();
                                }
                            } catch (Exception ex) {
                                LogUtils.WriteExceptionLog("释放TCP资源异常", ex);
                            }
    
                        }
                    }
                });
            }
    
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127
    • 128
    • 129
    • 130
    • 131
    • 132
    • 133
    • 134
    • 135
    • 136
    • 137
    • 138
    • 139
    • 140
    • 141
    • 142
    • 143
    • 144
    • 145
    • 146
    • 147
    • 148
    • 149
    • 150
    • 151
    • 152
    • 153
    • 154
    • 155
    • 156
    • 157
    • 158
    • 159
    • 160
    • 161
    • 162
    • 163
    • 164
    • 165
    • 166
    • 167
    • 168
    • 169
    • 170
    • 171
    • 172
    • 173
    • 174
    • 175
    • 176
    • 177
    • 178
    • 179
    • 180
    • 181
    • 182
    • 183
    • 184
    • 185
    • 186
    • 187
    • 188
    • 189
    • 190
    • 191
    • 192
    • 193
    • 194
    • 195
    • 196
    • 197
    • 198
    • 199
    • 200
    • 201
    • 202
    • 203
    • 204
    • 205
    • 206
    • 207
    • 208
    • 209
    • 210
    • 211
    • 212
    • 213
    • 214
    • 215
    • 216
    • 217
    • 218
    • 219
    • 220
    • 221
    • 222
    • 223
    • 224
    • 225
    • 226
    • 227
    • 228
    • 229
    • 230
    • 231
    • 232
    • 233
    • 234
    • 235
    • 236
    • 237
    • 238
    • 239
    • 240
    • 241
    • 242
    • 243
    • 244
    • 245
    • 246
    • 247
    • 248
    • 249
    • 250
    • 251
    • 252
    • 253
    • 254
    • 255
    • 256
    • 257
    • 258
    • 259
    • 260
    • 261
    • 262
    • 263
    • 264
    • 265
    • 266
    • 267
    • 268
    • 269
    • 270
    • 271
    • 272
    • 273
    • 274
    • 275
    • 276
    • 277
    • 278
    • 279
    • 280
    • 281
    • 282
    • 283
    • 284
    • 285
    • 286
    • 287
    • 288
    • 289
    • 290
    • 291
    • 292
    • 293

    然后为了统一管理所有TCP仪器提供MachManager,接口开发者之需要关心GetMachSocketBase方法

    package LIS.Core.Socket;
    
    import java.util.Iterator;
    import java.util.Map;
    import java.util.concurrent.ConcurrentHashMap;
    import LIS.Core.Socket.MachSocketBase;
    import LIS.Core.Socket.IMachDealData;
    
    /**
     * 统一管理所有仪器的MachSocketBase对象
     */
    public class MachManager {
        /**
         * 存所有仪器连接
         */
        public static ConcurrentHashMap<String, MachSocketBase> AllMach = new ConcurrentHashMap<>();
    
        /**
         * 更新处理接口对象
         * @param dealClass
         * @throws Exception
         */
        public static void UpdateDeal(Class dealClass) throws Exception
        {
            String dealClsName=dealClass.getName();
            for (Map.Entry<String, MachSocketBase> entry : AllMach.entrySet()) {
                String key = entry.getKey();
                MachSocketBase value = entry.getValue();
                if(value.DealClassName.equals(dealClsName))
                {
                    //创建对象
                    Object o = dealClass.getConstructor().newInstance();
                    value.DealObj=(IMachDealData)o;
                    System.out.println("更新:"+value.ID+"的数据处理类");
                }
            }
        }
    
        /**
         * 得到仪器连接的Socket管理类,直接就启动了控制了
         * @param ip IP地址,当服务端传空串
         * @param port 端口
         * @param upPeriod 上传毫秒间隔,不是主动上传的传null
         * @param dealObj 处理接口实现类
         * @param encode 编码格式,传null或空串默认为GBK
         * @return
         */
        public static MachSocketBase GetMachSocketBase(String ip, int port, Long upPeriod, IMachDealData dealObj, String encode)
        {
            MachSocketBase base=new MachSocketBase(ip,port,upPeriod,dealObj,encode);
            //注册到管理
            RegisterMachSocketBase(base);
            return base;
        }
    
        /**
         * 注册到管理
         * @param base
         */
        public static void RegisterMachSocketBase(MachSocketBase base)
        {
            //先停止老的接口
            if(AllMach.containsKey(base.ID))
            {
                AllMach.get(base.ID).Stop();
                AllMach.remove(base.ID);
            }
            //加入管理
            AllMach.put(base.ID,base);
            base.Start();
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73

    然后为了解决修改仪器接口脚本后实时生效实现仪器注解,接口修改后会自动调用MachManager.UpdateDeal更新处理类,这样不用频繁重启仪器控制

    //特性,申明此特性的仪器接口在修改后自动调用启动
    package LIS.Core.CustomAttributes;
    
    import java.lang.annotation.ElementType;
    import java.lang.annotation.Retention;
    import java.lang.annotation.RetentionPolicy;
    import java.lang.annotation.Target;
    
    /**
     * 申明此特性的仪器接口在修改后自动调用启动
     */
    @Target({ElementType.TYPE})
    @Retention(RetentionPolicy.RUNTIME)
    public @interface  Mach {
    
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    在这里插入图片描述

    然后实现一个实例仪器接口
    在这里插入图片描述

    import LIS.Core.CustomAttributes.Mach;
    import LIS.Core.Socket.IMachDealData;
    import LIS.Core.Socket.MachSocketBase;
    import appcode.BaseHttpHandlerNoSession;
    import appcode.Helper;
    
    import java.io.OutputStream;
    import java.io.OutputStreamWriter;
    import java.io.PrintWriter;
    import java.net.Socket;
    
    /**
     *连仪器示例代码
     */
    @Mach
    public class MachDemo extends BaseHttpHandlerNoSession implements IMachDealData {
        /**
         * 缓存数据
         */
        private static StringBuilder dataCache=new StringBuilder();
    
        //换行符
        private static String lineStr=System.getProperty("line.separator");
    
        /**
         * 显示日志
         * http://localhost:8080/ankilis/mi/MachDemo.ashx?Method=ShowLog
         * @return
         */
        public String ShowLog()
        {
            return dataCache.toString();
        }
    
        /**
         * 启动控制
         * http://localhost:8080/ankilis/mi/MachDemo.ashx?Method=Start
         * @return
         * @throws Exception
         */
        public String Start() throws Exception
        {
            //ip地址
            String ip=Helper.ValidParam(LIS.Core.MultiPlatform.LISContext.GetRequest(Request, "ip"), "");
            //端口
            int port=Helper.ValidParam(LIS.Core.MultiPlatform.LISContext.GetRequest(Request, "port"), 8888);
            MachSocketBase base=LIS.Core.Socket.MachManager.GetMachSocketBase(ip,port,Long.valueOf(5000),this,"GBK");
            if(base.Err.isEmpty())
            {
                return Helper.Success();
            }
            else
            {
                return Helper.Error(base.Err);
            }
        }
    
        /**
         * 处理上传定时器接口
         * @param sender Socket对象,用来发送比特用
         * @param writer 用来发布初始化指定的字符用
         */
        public void DealUpTimer(Socket sender, PrintWriter writer)
        {
            String sendStr="H->M:我主动定时给你推送的数据
    "
    ; //返回数据 writer.print(sendStr); writer.flush(); dataCache.append(sendStr+lineStr); } /** * 处理数据接收 * @param data 公共层处理成字符串的数据 * @param buf 没处理的比特数组 * @param sender Socket对象,用来发送比特用 * @param writer 用来发布初始化指定的字符用 */ public void DealReceive(String data, byte[] buf, Socket sender, PrintWriter writer) { //缓存数据 dataCache.append("M->H:"+data+lineStr); String sendStr="H->M:我收到你发给我的:"+data+"
    "
    ; //返回数据 writer.print(sendStr); writer.flush(); dataCache.append(sendStr+lineStr); } }
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90

    启动控制
    在这里插入图片描述

    在这里插入图片描述

    在这里插入图片描述

    这样就可以在这个基础上轻松连接TCP的仪器了,还是脚本化、还不用来回重启控制

  • 相关阅读:
    【原创工具】ADBGUI - GUI版ADB操作工具
    备战2022.9.15数学建模
    Eureka介绍与使用
    ORB-SLAM2从理论到代码实现(十):LoopClosing程序详解
    带你了解5个幽灵攻击与编译器中的消减方法
    [uni-app]记录APP端跳转页面自动滚动到底部的bug
    判断二叉树是否为二叉搜索树
    【2205.05740v2】Surface Representation for Point Clouds
    未登录也能知道你是谁?浏览器指纹了解一下!
    Java复习总结之I/O流
  • 原文地址:https://blog.csdn.net/zhanglianzhu_91/article/details/134538173