whycq
2024-11-21 c370397fe6c7552bb63f2580233c4b233f0ff56c
#websocket
1个文件已修改
2个文件已添加
302 ■■■■■ 已修改文件
pom.xml 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/timer/LedWebsocket.java 176 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/common/config/WebSocketServer.java 116 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pom.xml
@@ -31,6 +31,16 @@
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-websocket</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-websocket</artifactId>
        </dependency>
        <dependency>
            <groupId>cn.hutool</groupId>
            <artifactId>hutool-all</artifactId>
            <version>5.8.26</version>
        </dependency>
        <!--<dependency>-->
            <!--<groupId>org.springframework.boot</groupId>-->
            <!--<artifactId>spring-boot-starter-tomcat</artifactId>-->
src/main/java/com/zy/asrs/timer/LedWebsocket.java
New file
@@ -0,0 +1,176 @@
package com.zy.asrs.timer;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.core.common.Arith;
import com.core.common.Cools;
import com.zy.asrs.domain.dto.AxisBean;
import com.zy.asrs.domain.dto.WorkChartAxis;
import com.zy.asrs.domain.vo.LocChartPie;
import com.zy.asrs.entity.LocDetl;
import com.zy.asrs.mapper.ReportQueryMapper;
import com.zy.asrs.service.LocDetlService;
import com.zy.common.config.WebSocketServer;
import com.zy.common.service.CommonService;
import com.zy.core.cache.SlaveConnection;
import com.zy.core.enums.SlaveType;
import com.zy.core.model.LedSlave;
import com.zy.core.model.command.LedCommand;
import com.zy.core.properties.SlaveProperties;
import com.zy.core.thread.LedThread;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import java.text.SimpleDateFormat;
import java.util.*;
@Component
@Slf4j
public class LedWebsocket {
    private static final String[] WEEK = {"星期日","星期一","星期二","星期三","星期四","星期五","星期六"};
    @Autowired
    private ReportQueryMapper reportQueryMapper;
    @Autowired
    private SlaveProperties slaveProperties;
    @Autowired
    private WebSocketServer webSocketServer;
    @Autowired
    private LocDetlService locDetlService;
    @Scheduled(cron = "0/2 * * * * ? ")
    private void send() {
        //饼图
        List<Map<String, Object>> pie = new ArrayList<>();
        LocChartPie locUseRate = reportQueryMapper.getLocUseRate();
        if(locUseRate!=null) {
            Map<String, Object> map = new HashMap<>();
            map.put("name", "在库");
            map.put("value", locUseRate.getFqty());
            pie.add(map);
            Map<String, Object> map1 = new HashMap<>();
            map1.put("name", "空");
            map1.put("value", locUseRate.getOqty());
            pie.add(map1);
            Map<String, Object> map2 = new HashMap<>();
            map2.put("name", "使用");
            map2.put("value", locUseRate.getUqty());
            pie.add(map2);
            Map<String, Object> map3 = new HashMap<>();
            map3.put("name", "禁用");
            map3.put("value", locUseRate.getXqty());
            pie.add(map3);
        }
        // 总库位数
        Integer total = (int) Arith.add(0, locUseRate.getFqty(), locUseRate.getOqty(), locUseRate.getUqty(), locUseRate.getXqty());
        // 使用中
        Integer used = locUseRate.getFqty() + locUseRate.getUqty();
        // 库位使用率
        double usedDivides = Arith.divides(3, used, total);
        double usedPr = Arith.multiplys(1, usedDivides, 100);
        //折线图
        Map<String,Object> map=new HashMap<String, Object>();
        List<AxisBean> list = new ArrayList<AxisBean>();
        List<WorkChartAxis> listChart = reportQueryMapper.getChartAxis();
        if(listChart!=null) {
            ArrayList<Integer> data1 = new ArrayList<Integer>();
            ArrayList<Integer> data2 = new ArrayList<Integer>();
            SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd");
            Calendar calendar = Calendar.getInstance();
            calendar.add(Calendar.DATE, -12);
            for(int i=0;i<12;i++) {
                boolean flag = true;
                calendar.add(Calendar.DATE, 1);
                String str = sf.format(calendar.getTime());
                for(WorkChartAxis workChart : listChart) {
                    if(str.equals(workChart.getYmd())) {
                        data1.add(workChart.getInqty());
                        data2.add(workChart.getOutqty());
                        flag = false;
                        break;
                    }
                }
                if(flag) {
                    data1.add(0);
                    data2.add(0);
                }
            }
            AxisBean inqty = new AxisBean();
            inqty.setName("入库数量");
            Integer[] array1 = new Integer[data1.size()];
            inqty.setData(data1.toArray(array1));
            list.add(inqty);
            AxisBean outqty = new AxisBean();
            outqty.setName("出库数量");
            Integer[] array2 = new Integer[data2.size()];
            outqty.setData(data2.toArray(array2));
            list.add(outqty);
        }
        //仓库数据
        EntityWrapper<LocDetl> locDetlEntityWrapper = new EntityWrapper<>();
        locDetlEntityWrapper.setSqlSelect("matnr,COUNT(*) as matnrCount").groupBy("matnr");
        List<Map<String, Object>>  selectMap = locDetlService.selectMaps(locDetlEntityWrapper);
        Date now = new Date();
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(now);
//         Map<String, Object> map = new HashMap<>();
         map.put("to","all");
         map.put("message", Cools.add("type", "default").add("pie", pie)
                 .add("stockCunt", locUseRate.getFqty())
                 .add("emptyCount", locUseRate.getOqty())
                 .add("noneCount", locUseRate.getXqty())
                 .add("total", total)
                 .add("used", used)
                 .add("usedPr", usedPr)
                 .add("rows",list)
                 .add("year", calendar.get(Calendar.YEAR))
                 .add("month", CommonService.zerofill(String.valueOf(calendar.get(Calendar.MONTH)+1), 2))
                 .add("day", CommonService.zerofill(String.valueOf(calendar.get(Calendar.DATE)), 2))
                 .add("hour", CommonService.zerofill(String.valueOf(calendar.get(Calendar.HOUR_OF_DAY)), 2))
                 .add("minute", CommonService.zerofill(String.valueOf(calendar.get(Calendar.MINUTE)), 2))
                 .add("second", CommonService.zerofill(String.valueOf(calendar.get(Calendar.SECOND)) , 2))
                 .add("week", WEEK[calendar.get(Calendar.DAY_OF_WEEK)-1])
                 .add("inventoryData",selectMap));
        webSocketServer.onMessage(JSONObject.toJSONString(map),null,"all");
    }
    @Scheduled(cron = "0/2 * * * * ? ")
    private void errorSend(){
        Map<String,Object> map=new HashMap<String, Object>();
        for (LedSlave slave : slaveProperties.getLed()) {
                LedThread ledThread = (LedThread) SlaveConnection.get(SlaveType.Led, slave.getId());
                if (null != ledThread) {
                    map.put("to",slave.getStaArr().get(0).toString());
                    map.put("message",Cools.add("type", "error").add("errMsg",ledThread.getErrorMsg().toString()));
                    webSocketServer.onMessage(JSONObject.toJSONString(map),null,slave.getStaArr().get(0).toString());
                }
        }
    }
    @Scheduled(cron = "0/2 * * * * ? ")
    private void TaskSend(){
        Map<String,Object> map=new HashMap<String, Object>();
        List<LedCommand> commandList = null;
        for (LedSlave slave : slaveProperties.getLed()) {
                LedThread ledThread = (LedThread) SlaveConnection.get(SlaveType.Led, slave.getId());
                if (null != ledThread) {
                    map.put("to",slave.getStaArr().get(0).toString());
                    map.put("message",Cools.add("type", "task").add("taskList",ledThread.getCommandList()));
                    webSocketServer.onMessage(JSONObject.toJSONString(map),null,slave.getStaArr().get(0).toString());
                }
        }
    }
}
src/main/java/com/zy/common/config/WebSocketServer.java
New file
@@ -0,0 +1,116 @@
package com.zy.common.config;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;
import javax.websocket.*;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
@ServerEndpoint(value = "/led/{username}")
@Component
@Service
public class WebSocketServer {
    private static final Logger log = LoggerFactory.getLogger(WebSocketServer.class);
    /**
     * 记录当前在线连接数
     */
    public static final Map<String, Session> sessionMap = new ConcurrentHashMap<>();
    /**
     * 连接建立成功调用的方法
     */
    @OnOpen
    public void onOpen(Session session, @PathParam("username") String username) {
        sessionMap.put(username, session);
        log.info("有新用户加入,username={}, 当前在线人数为:{}", 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);
            // {"username", "zhang", "username": "admin"}
            array.add(jsonObject);
        }
//        {"users": [{"username": "zhang"},{ "username": "admin"}]}
        sendAllMessage(JSONUtil.toJsonStr(result));  // 后台发送消息给所有的客户端
    }
    /**
     * 连接关闭调用的方法
     */
    @OnClose
    public void onClose(Session session, @PathParam("username") String username) {
        sessionMap.remove(username);
        log.info("有一连接关闭,移除username={}的用户session, 当前在线人数为:{}", username, sessionMap.size());
    }
    /**
     * 收到客户端消息后调用的方法
     * 后台收到客户端发送过来的消息
     * onMessage 是一个消息的中转站
     * 接受 浏览器端 socket.send 发送过来的 json数据
     * @param message 客户端发送过来的消息
     */
    @OnMessage
    public void onMessage(String message, Session session, @PathParam("username") String username) {
//        log.info("服务端收到用户username={}的消息:{}", username, message);
        JSONObject obj = JSONUtil.parseObj(message);
        String toUsername = obj.getStr("to"); // to表示发送给哪个用户,比如 admin
        String text = obj.getStr("message"); // 发送的消息文本  hello
        // {"to": "admin", "text": "聊天文本"}
        if ("heartBeat".equals(toUsername)) {
            log.info("心跳");
        }else if ("all".equals(toUsername)) {
            sendAllMessage(text);
        }else {
            Session toSession = sessionMap.get(toUsername); // 根据 to用户名来获取 session,再通过session发送消息文本
            if (toSession != null) {
                // 服务器端 再把消息组装一下,组装后的消息包含发送人和发送的文本内容
                // {"from": "zhang", "text": "hello"}
                JSONObject jsonObject = new JSONObject();
                jsonObject.set("from", username);  // from 是 zhang
                jsonObject.set("text", text);  // text 同上面的text
                this.sendMessage(text, toSession);
//            log.info("发送给用户username={},消息:{}", toUsername, jsonObject.toString());
            } else {
//                log.info("发送失败,未找到用户username={}的session", toUsername);
            }
        }
    }
    @OnError
    public void onError(Session session, Throwable error) {
        log.error("发生错误");
        error.printStackTrace();
    }
    /**
     * 服务端发送消息给客户端
     */
    private void sendMessage(String message, Session toSession) {
        try {
//            log.info("服务端给客户端[{}]发送消息{}", toSession.getId(), message);
            toSession.getBasicRemote().sendText(message);
        } catch (Exception e) {
            log.error("服务端发送消息给客户端失败", e);
        }
    }
    /**
     * 服务端发送消息给所有客户端
     */
    private void sendAllMessage(String message) {
        try {
            for (Session session : sessionMap.values()) {
//                log.info("服务端给客户端[{}]发送消息{}", session.getId(), message);
                session.getBasicRemote().sendText(message);
            }
        } catch (Exception e) {
            log.error("服务端发送消息给客户端失败", e);
        }
    }
}