From 2546b2505f9c6d19a1fa16ff09d24ac4988a7127 Mon Sep 17 00:00:00 2001
From: zhangyong <517047165@qq.com>
Date: 星期五, 01 九月 2023 11:08:06 +0800
Subject: [PATCH] 提交S7通讯代码和websocket演示用代码

---
 springboot-vue3/src/main/java/com/example/springboot/component/WebSocketServer.java |  118 +++++++++++++
 springboot-vue3/src/main/java/com/example/springboot/config/WebSocketConfig.java    |   16 +
 springboot-vue3/src/main/java/com/example/springboot/config/AppRunnerConfig.java    |   21 ++
 CanadaMes-ui/src/router/index.js                                                    |    5 
 springboot-vue3/pom.xml                                                             |    9 +
 springboot-vue3/src/main/java/com/example/springboot/component/PlcHold.java         |   36 ++++
 springboot-vue3/src/main/java/com/example/springboot/component/S7control.java       |  219 ++++++++++++++++++++++++
 CanadaMes-ui/package-lock.json                                                      |    2 
 CanadaMes-ui/src/views/device/talkvue.vue                                           |   69 +++++++
 9 files changed, 494 insertions(+), 1 deletions(-)

diff --git a/CanadaMes-ui/package-lock.json b/CanadaMes-ui/package-lock.json
index dd945e1..12e4be0 100644
--- a/CanadaMes-ui/package-lock.json
+++ b/CanadaMes-ui/package-lock.json
@@ -5,7 +5,7 @@
   "requires": true,
   "packages": {
     "": {
-      "name": "canadames",
+      "name": "springboot-vue3",
       "version": "0.1.0",
       "dependencies": {
         "axios": "^0.19.2",
diff --git a/CanadaMes-ui/src/router/index.js b/CanadaMes-ui/src/router/index.js
index 03377b2..83e8e75 100644
--- a/CanadaMes-ui/src/router/index.js
+++ b/CanadaMes-ui/src/router/index.js
@@ -49,6 +49,11 @@
 
       },
       {
+        path: '/device/talk',
+        component: () => import('../views/device/talkvue'),
+
+      },
+      {
         path: '/device/alarm',
         component: () => import('../views/device/alarm')
       },
diff --git a/CanadaMes-ui/src/views/device/talkvue.vue b/CanadaMes-ui/src/views/device/talkvue.vue
new file mode 100644
index 0000000..96afec3
--- /dev/null
+++ b/CanadaMes-ui/src/views/device/talkvue.vue
@@ -0,0 +1,69 @@
+<template>
+  <!-- <button v-on:click="send">娴嬭瘯鍙戦��</button> -->
+  <button @click="send()">娴嬭瘯鍙戦��</button>
+</template>
+    
+<script>
+let socket;
+export default {
+  name: "talkvue",
+ 
+  data() {
+    return {
+      messagepack: {
+        data: { taskname:"" }
+      },
+      queryInfo: {
+        data: "1",
+        pageSize: 10
+      },
+    };
+  },
+  created() {
+    this.init();
+  },
+  methods:
+  {
+    init() {
+      let viewname = "talkvue";
+
+      if (typeof (WebSocket) == "undefined") {
+        console.log("鎮ㄧ殑娴忚鍣ㄤ笉鏀寔WebSocket");
+      } else {
+        //console.log("鎮ㄧ殑娴忚鍣ㄦ敮鎸乄ebSocket");
+
+        let socketUrl = "ws://" + "localhost:8888" + "/springboot-vue3/api/talk/" + viewname;
+        if (socket != null) {
+          socket.close();
+          socket = null;
+        }
+        // 寮�鍚竴涓獁ebsocket鏈嶅姟
+        socket = new WebSocket(socketUrl);
+        //鎵撳紑浜嬩欢
+        socket.onopen = function () {
+          console.log("websocket宸叉墦寮�");
+        };
+        //  娴忚鍣ㄧ鏀舵秷鎭紝鑾峰緱浠庢湇鍔$鍙戦�佽繃鏉ョ殑鏂囨湰娑堟伅
+        socket.onmessage = function (msg) {
+          console.log("鏀跺埌鏁版嵁====" + msg.data)
+
+          //let data = JSON.parse(msg.data)  // 瀵规敹鍒扮殑json鏁版嵁杩涜瑙f瀽锛� 绫讳技杩欐牱鐨勶細 {"users": [{"username": "zhang"},{ "username": "admin"}]}
+
+        };
+        //鍏抽棴浜嬩欢
+        socket.onclose = function () {
+          console.log("websocket宸插叧闂�");
+        };
+        //鍙戠敓浜嗛敊璇簨浠�
+        socket.onerror = function () {
+          console.log("websocket鍙戠敓浜嗛敊璇�");
+        }
+      }
+    },
+    send() {
+      this.messagepack.data =  {taskname:"鍓嶇鍒板悗鍙�"} ;
+      socket?.send(JSON.stringify(this.messagepack));  // 灏嗙粍瑁呭ソ鐨刯son鍙戦�佺粰鏈嶅姟绔紝鐢辨湇鍔$杩涜杞彂
+    }
+  }
+}
+</script>
\ No newline at end of file
diff --git a/springboot-vue3/pom.xml b/springboot-vue3/pom.xml
index 48b9acd..c591f41 100644
--- a/springboot-vue3/pom.xml
+++ b/springboot-vue3/pom.xml
@@ -118,7 +118,16 @@
             <artifactId>poi-tl</artifactId>
             <version>1.12.1</version>
         </dependency>
+        <dependency>
+            <groupId>com.github.xingshuangs</groupId>
+            <artifactId>iot-communication</artifactId>
+            <version>1.4.2</version>
+        </dependency>
 
+         <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-websocket</artifactId>
+         </dependency>
     </dependencies>
 
     <build>
diff --git a/springboot-vue3/src/main/java/com/example/springboot/component/PlcHold.java b/springboot-vue3/src/main/java/com/example/springboot/component/PlcHold.java
new file mode 100644
index 0000000..abf3fff
--- /dev/null
+++ b/springboot-vue3/src/main/java/com/example/springboot/component/PlcHold.java
@@ -0,0 +1,36 @@
+package com.example.springboot.component;
+
+import java.util.List;
+
+import javax.websocket.Session;
+
+import cn.hutool.json.JSONArray;
+import cn.hutool.json.JSONObject;
+
+public class PlcHold extends Thread {
+    @Override
+    public void run() {
+        while (this != null) {
+            try {
+
+                Thread.sleep(15000);
+            } catch (InterruptedException e) {
+                // TODO Auto-generated catch block
+                e.printStackTrace();
+            }
+            List<Boolean> bitlist = S7control.getinstance().ReadBits("DB2.0.0", 100);
+
+            List<Short> paramlist = S7control.getinstance().ReadWord("DB100.6", 1);
+
+            //鏌ヨ鏁版嵁搴�
+            //鎺ㄩ�佸埌鍓嶇
+
+            JSONObject jsonObject = new JSONObject();
+            jsonObject.append("params", new short[] { 0, 1, 2, 3, 4, 5, });
+            WebSocketServer sendwServer = WebSocketServer.sessionMap.get("talkvue");
+            if (sendwServer != null) {
+                sendwServer.sendMessage(jsonObject.toString());
+            }
+        }
+    }
+}
diff --git a/springboot-vue3/src/main/java/com/example/springboot/component/S7control.java b/springboot-vue3/src/main/java/com/example/springboot/component/S7control.java
new file mode 100644
index 0000000..5942a98
--- /dev/null
+++ b/springboot-vue3/src/main/java/com/example/springboot/component/S7control.java
@@ -0,0 +1,219 @@
+package com.example.springboot.component;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import com.github.xingshuangs.iot.protocol.s7.enums.EPlcType;
+import com.github.xingshuangs.iot.protocol.s7.service.MultiAddressWrite;
+import com.github.xingshuangs.iot.protocol.s7.service.S7PLC;
+
+public class S7control {
+
+    S7PLC s7PLC; // PLC閫氳绫诲疄渚�
+    private EPlcType plcType = EPlcType.S1200; // 瑗块棬瀛怭LC绫诲瀷
+    private String ip = "127.0.0.1"; // plc ip鍦板潃
+    private int port = 21; // plc 绔彛鍙�
+
+    private static volatile S7control instance = null;
+
+    private S7control() {
+        if (s7PLC == null)
+            s7PLC = new S7PLC(plcType, ip, port);
+    }
+
+    // 鍗曚緥妯″紡 鑾峰彇绫荤殑鍞竴瀹炰緥
+    public static S7control getinstance() {
+        if (instance == null) {
+            synchronized (S7control.class) {
+                if (instance == null)
+                    instance = new S7control();
+            }
+        }
+        return instance;
+    }
+
+    /**
+     * 鍏抽棴瑗块棬瀛恠7閫氳杩炴帴
+     */
+    public void CloseS7client() {
+        if (s7PLC == null)
+            s7PLC.close();
+    }
+
+    /**
+     * 鎸夋寚瀹氱殑鍦板潃 鍐欏叆涓�涓獁ord
+     * 
+     * @param address 鍦板潃
+     * @param data    word鐨勫��
+     */
+    public void WriteWord(String address, short data) {
+        if (!s7PLC.checkConnected())
+            return;
+        s7PLC.writeInt16(address, data);
+    }
+
+    /**
+     * 浠庢煇鍦板潃杩炵画 鍐欏叆澶氫釜word
+     * 
+     * @param address 鍦板潃
+     * @param datas   word鐨勫��
+     */
+    public void WriteWord(String address, List<Short> datas) {
+        if (!s7PLC.checkConnected())
+            return;
+        // s7PLC.write(address, data);
+        List<String> addresslist = GetAddressList(address, datas.size(), 16);
+        MultiAddressWrite addressWrite = new MultiAddressWrite();
+        for (int i = 0; i < datas.size(); i++) {
+            addressWrite.addInt16(addresslist.get(i), datas.get(i));
+        }
+        s7PLC.writeMultiData(addressWrite);
+    }
+
+    /**
+     * 鎸夋寚瀹氱殑鍦板潃 鍐欏叆澶氫釜word
+     * 
+     * @param address 鍦板潃
+     * @param datas   word鐨勫��
+     */
+    public void WriteWord(List<String> address, List<Short> datas) {
+        if (!s7PLC.checkConnected())
+            return;
+        // s7PLC.write(address, data);
+
+        MultiAddressWrite addressWrite = new MultiAddressWrite();
+        for (int i = 0; i < address.size(); i++) {
+            addressWrite.addInt16(address.get(i), datas.get(i));
+        }
+        s7PLC.writeMultiData(addressWrite);
+    }
+
+    /**
+     * 鎸夋寚瀹氱殑鍦板潃 鍐欏叆涓�涓狟it
+     * 
+     * @param address 鍦板潃
+     * @param data    Bit鐨勫��
+     */
+    public void WriteBit(String address, Boolean data) {
+        if (!s7PLC.checkConnected())
+            return;
+        s7PLC.writeBoolean(address, data);
+    }
+
+    /**
+     * 鎸夋寚瀹氱殑鍦板潃 鍐欏叆澶氫釜bit
+     * 
+     * @param address 鍦板潃
+     * @param datas   bit鐨勫��
+     */
+    public void WriteBit(List<String> address, List<Boolean> datas) {
+        if (!s7PLC.checkConnected())
+            return;
+        // s7PLC.write(address, data);
+
+        MultiAddressWrite addressWrite = new MultiAddressWrite();
+        for (int i = 0; i < address.size(); i++) {
+            addressWrite.addBoolean(address.get(i), datas.get(i));
+        }
+        s7PLC.writeMultiData(addressWrite);
+    }
+
+    /**
+     * 浠庢煇鍦板潃杩炵画 鍐欏叆澶氫釜bit
+     * 
+     * @param address 鍦板潃
+     * @param datas   word鐨勫��
+     */
+    public void WriteBit(String address, List<Boolean> datas) {
+        if (!s7PLC.checkConnected())
+            return;
+        // s7PLC.write(address, data);
+        List<String> addresslist = GetAddressList(address, datas.size(), 1);
+        MultiAddressWrite addressWrite = new MultiAddressWrite();
+        for (int i = 0; i < datas.size(); i++) {
+            addressWrite.addBoolean(addresslist.get(i), datas.get(i));
+        }
+        s7PLC.writeMultiData(addressWrite);
+    }
+
+    /**
+     * 鎸夋寚瀹氱殑鍦板潃 璇诲彇word缁撴灉闆�
+     * 
+     * @param address 鍦板潃
+     * @return 缁撴灉
+     */
+    public List<Short> ReadWord(List<String> address) {
+        if (!s7PLC.checkConnected())
+            return null;
+        return s7PLC.readInt16(address);
+    }
+
+    /**
+     * 鎸夋寚瀹氱殑鍦板潃 璇诲彇word缁撴灉闆�
+     * 
+     * @param address 鍦板潃
+     * @param count   杩炵画璇诲灏戜釜word
+     * @return 缁撴灉
+     */
+    public List<Short> ReadWord(String address, int count) {
+        if (!s7PLC.checkConnected())
+            return null;
+
+        List<String> addresslist = GetAddressList(address, count, 16);
+        return s7PLC.readInt16(addresslist);
+    }
+
+    /**
+     * 鎸夋寚瀹氱殑鍦板潃 鎸塨it浣� 0 flase 1 true 璇诲彇缁撴灉
+     *
+     * @param addresslist 鍦板潃闆�
+     * @return Boolean缁撴灉
+     */
+    public List<Boolean> ReadBits(List<String> addresslist) {
+        if (!s7PLC.checkConnected())
+            return null;
+        return s7PLC.readBoolean(addresslist);
+    }
+
+    /**
+     * 浠庢寚瀹氱殑鍦板潃寮�濮� 杩炵画鎸塨it浣嶈鍙�
+     *
+     * @param address 鍦板潃
+     * @param count   闀垮害
+     * @return Boolean缁撴灉
+     */
+    public List<Boolean> ReadBits(String address, int count) {
+        if (!s7PLC.checkConnected())
+            return null;
+        List<String> addresslist = GetAddressList(address, count, 1);
+        return s7PLC.readBoolean(addresslist);
+    }
+
+    private List<String> GetAddressList(String address, int count, int addedbit) {
+        List<String> addresslist = new ArrayList<>();
+
+        String[] stringdatas = address.split(".");
+        if (stringdatas.length < 2 || !address.startsWith("DB"))
+            return null;
+        int dbwindex = 0;
+        int bitindex = 0;
+        if (stringdatas.length == 2) {
+            dbwindex = Integer.parseInt(stringdatas[1]);
+        } else if (stringdatas.length == 3) {
+            bitindex = Integer.parseInt(stringdatas[2]);
+        } else
+            return null;
+
+        for (int i = 0; i < count; i++) {
+
+            int bitcurrent = bitindex + addedbit;
+            if (bitcurrent > 7) {
+                dbwindex += bitcurrent / 8;
+                bitindex = 0;
+            } else
+                bitindex = bitcurrent;
+            addresslist.add(stringdatas[0] + "." + dbwindex + "." + bitindex);
+        }
+        return addresslist;
+    }
+}
diff --git a/springboot-vue3/src/main/java/com/example/springboot/component/WebSocketServer.java b/springboot-vue3/src/main/java/com/example/springboot/component/WebSocketServer.java
new file mode 100644
index 0000000..18785c1
--- /dev/null
+++ b/springboot-vue3/src/main/java/com/example/springboot/component/WebSocketServer.java
@@ -0,0 +1,118 @@
+package com.example.springboot.component;
+
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+
+import javax.websocket.OnClose;
+import javax.websocket.OnError;
+import javax.websocket.OnMessage;
+import javax.websocket.OnOpen;
+import javax.websocket.Session;
+import javax.websocket.server.PathParam;
+import javax.websocket.server.ServerEndpoint;
+
+import org.springframework.stereotype.Component;
+
+
+import cn.hutool.json.JSONObject;
+import cn.hutool.json.JSONUtil;
+
+@ServerEndpoint(value = "/api/talk/{username}")
+@Component
+public class WebSocketServer {
+    
+   private static final Logger log = LoggerFactory.getLogger(WebSocketServer.class);
+
+    /**
+     * 璁板綍褰撳墠鍦ㄧ嚎杩炴帴鏁�
+     */
+    public static final Map<String, WebSocketServer> sessionMap = new ConcurrentHashMap<>();
+    
+    private String username;
+    private Session session;
+    /**
+     * 杩炴帴寤虹珛鎴愬姛璋冪敤鐨勬柟娉�
+     */
+    @OnOpen
+    public void onOpen(Session session, @PathParam("username") String username) {
+        this.username=username;
+        this.session=session;
+        sessionMap.put(username, this);
+        log.info("鏈夋柊鐢ㄦ埛鍔犲叆锛寀sername={}, 褰撳墠鍦ㄧ嚎浜烘暟涓猴細{}", username, sessionMap.size());
+       
+        // JSONObject result = new JSONObject();
+        // JSONArray array = new JSONArray();
+        // result.set("users", array);
+        // for (Object key : sessionMap.keySet()) {
+        //     JSONObject jsonObject = new JSONObject();
+        //     jsonObject.set("username", key); 
+        //     array.add(jsonObject);
+        // }
+   
+        //sendAllMessage(JSONUtil.toJsonStr(result));  // 鍚庡彴鍙戦�佹秷鎭粰鎵�鏈夌殑瀹㈡埛绔�
+    }
+
+    /**
+     * 杩炴帴鍏抽棴璋冪敤鐨勬柟娉�
+     */
+    @OnClose
+    public void onClose(Session session, @PathParam("username") String username) {
+        sessionMap.remove(username);
+        log.info("鏈変竴杩炴帴鍏抽棴锛岀Щ闄sername={}鐨勭敤鎴穝ession, 褰撳墠鍦ㄧ嚎浜烘暟涓猴細{}", username, sessionMap.size());
+    }
+
+    /**
+     * 鏀跺埌瀹㈡埛绔秷鎭悗璋冪敤鐨勬柟娉�
+     * 鍚庡彴鏀跺埌瀹㈡埛绔彂閫佽繃鏉ョ殑娑堟伅
+     * onMessage 鏄竴涓秷鎭殑涓浆绔�
+     * 鎺ュ彈 娴忚鍣ㄧ socket.send 鍙戦�佽繃鏉ョ殑 json鏁版嵁
+     * @param message 瀹㈡埛绔彂閫佽繃鏉ョ殑娑堟伅
+     */
+    @OnMessage
+    public void onMessage(String message, Session session, @PathParam("username") String username) {
+        log.info("鏈嶅姟绔敹鍒扮敤鎴穟sername={}鐨勬秷鎭�:{}", username, message);
+        JSONObject obj = JSONUtil.parseObj(message);
+        
+         String text = obj.getStr("data"); 
+
+         JSONObject jsonObject = new JSONObject();
+         jsonObject.set("message", "ngng"); 
+         this.sendMessage(jsonObject.toString()); //JSONUtil.toJsonStr(jsonObject)
+    }
+
+    @OnError
+    public void onError(Session session, Throwable error) {
+        log.error("鍙戠敓閿欒");
+        error.printStackTrace();
+    }
+
+    /**
+     * 鏈嶅姟绔彂閫佹秷鎭粰瀹㈡埛绔�
+     */
+    public void sendMessage(String message) {
+        try {
+            log.info("鏈嶅姟绔粰瀹㈡埛绔痆{}]鍙戦�佹秷鎭瘂}", this.session.getId(), message);
+            this.session.getBasicRemote().sendText(message);
+        } catch (Exception e) {
+            log.error("鏈嶅姟绔彂閫佹秷鎭粰瀹㈡埛绔け璐�", e);
+        }
+    }
+
+    /**
+     * 鏈嶅姟绔彂閫佹秷鎭粰鎵�鏈夊鎴风
+     */
+    public void sendAllMessage(String message) {
+        try {
+            for (WebSocketServer webSocketServer : sessionMap.values()) {
+                log.info("鏈嶅姟绔粰瀹㈡埛绔痆{}]鍙戦�佹秷鎭瘂}", this.session.getId(), message);
+                webSocketServer.sendMessage(message);
+            }
+        } catch (Exception e) {
+            log.error("鏈嶅姟绔彂閫佹秷鎭粰瀹㈡埛绔け璐�", e);
+        }
+    }
+
+}
diff --git a/springboot-vue3/src/main/java/com/example/springboot/config/AppRunnerConfig.java b/springboot-vue3/src/main/java/com/example/springboot/config/AppRunnerConfig.java
new file mode 100644
index 0000000..0973688
--- /dev/null
+++ b/springboot-vue3/src/main/java/com/example/springboot/config/AppRunnerConfig.java
@@ -0,0 +1,21 @@
+package com.example.springboot.config;
+
+import org.springframework.boot.ApplicationArguments;
+import org.springframework.boot.ApplicationRunner;
+import org.springframework.core.annotation.Order;
+import org.springframework.stereotype.Component;
+
+import com.example.springboot.component.PlcHold;
+
+@Component
+@Order(1)
+public class AppRunnerConfig implements ApplicationRunner{
+    @Override
+    public void run(ApplicationArguments args) throws Exception {
+        // TODO Auto-generated method stub
+       //
+       System.out.println("鍚姩瀹屾垚");
+       
+       new PlcHold().start();
+    }   
+}
diff --git a/springboot-vue3/src/main/java/com/example/springboot/config/WebSocketConfig.java b/springboot-vue3/src/main/java/com/example/springboot/config/WebSocketConfig.java
new file mode 100644
index 0000000..2c566bc
--- /dev/null
+++ b/springboot-vue3/src/main/java/com/example/springboot/config/WebSocketConfig.java
@@ -0,0 +1,16 @@
+package com.example.springboot.config;
+
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.web.socket.server.standard.ServerEndpointExporter;
+
+@Configuration
+public class WebSocketConfig {
+    
+
+     @Bean
+    public ServerEndpointExporter serverEndpointExporter() {
+        return new ServerEndpointExporter();
+    }
+
+}

--
Gitblit v1.8.0