websocket Messgae handle

该博客主要介绍了WebSocket连接的管理和消息处理。当WebSocket连接建立和关闭时,它会进行相应的设备状态更新和Redis操作。此外,它还解析并处理接收到的消息,包括订阅和客户端主动发送的消息。在接收到消息后,会调用`monitorWork`进行工作调度。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


@Component
public class MonitorWebSocketHandler implements WebSocketHandlerDecoratorFactory {

    @Resource
    private MonitorWork monitorWork;

    // @Resource
    // private IndexPageTopic indexTopic;

    private final static String HEAD_CMD = "cmd";

    @Override
    public WebSocketHandler decorate(WebSocketHandler handler) {
        return new WebSocketHandlerDecorator(handler) {
            @Override
            public void afterConnectionEstablished(final WebSocketSession session) throws Exception {
                super.afterConnectionEstablished(session);
            }

            @Override
            public void afterConnectionClosed(WebSocketSession session, CloseStatus closeStatus) throws Exception {
                //连接关闭-电池箱处理
                Set<Object> boxSubDevices = RedisUtil.HashOps.hKeys(RedisUtil.Helper.join(RedisKey.BOX_SUB_DEVICE_PREFIX, session.getId()));
                if (boxSubDevices.size() > 0) {
                    for (Object deviceCode : boxSubDevices) {
                        String incrKey = RedisUtil.Helper.join(RedisKey.BOX_MONITOR_INCR, deviceCode);
                        if (Integer.parseInt(RedisUtil.StringOps.get(incrKey)) > 0) {
                            RedisUtil.StringOps.incrBy(incrKey, -1);
                            RedisUtil.HashOps.hDelete(RedisUtil.Helper.join(RedisKey.BOX_SUB_DEVICE_PREFIX, session.getId()), deviceCode);
                        }
                        //小于等零时,移除
                        if (Integer.parseInt(RedisUtil.StringOps.get(incrKey)) <= 0) {
                            RedisUtil.SetOps.sRemove(RedisKey.BOX_MONITOR_TASK, deviceCode);
                        }
                    }
                    //删除当前Session订单的箱
                    RedisUtil.KeyOps.delete(RedisUtil.Helper.join(RedisKey.BOX_SUB_DEVICE_PREFIX, session.getId()));
                }

                //连接关闭-电池包处理
                Set<Object> pkgSubDevices = RedisUtil.HashOps.hKeys(RedisUtil.Helper.join(RedisKey.BOX_PKG_SUB_DEVICE_PREFIX, session.getId()));
                if (pkgSubDevices.size() > 0) {
                    for (Object deviceCode : pkgSubDevices) {
                        Set<Object> pkgSubSubSysIds = RedisUtil.HashOps.hKeys(RedisUtil.Helper.join(RedisKey.BOX_PACKAGE_MONITOR_TASK, deviceCode));
                        if (pkgSubSubSysIds.size() == 0) continue;
                        for (Object pkgSubSubSysId : pkgSubSubSysIds) {
                            String incrKey = RedisUtil.Helper.join(RedisKey.BOX_PACKAGE_MONITOR_INCR, deviceCode, pkgSubSubSysId);
                            if (Integer.parseInt(RedisUtil.StringOps.get(incrKey)) > 0) {
                                RedisUtil.StringOps.incrBy(incrKey, -1);
                                //删除订阅的包键
                                RedisUtil.HashOps.hDelete(RedisUtil.Helper.join(RedisKey.BOX_PACKAGE_MONITOR_TASK, deviceCode), pkgSubSubSysId);
                            }
                            //小于等零时,移除
                            if (Integer.parseInt(RedisUtil.StringOps.get(incrKey)) <= 0) {
                                RedisUtil.SetOps.sRemove(RedisKey.BOX_PACKAGE_MONITOR_TASK, deviceCode);
                            }
                        }
                    }
                    //删除当前Session订单的箱
                    RedisUtil.KeyOps.delete(RedisUtil.Helper.join(RedisKey.BOX_PKG_SUB_DEVICE_PREFIX, session.getId()));
                }

                super.afterConnectionClosed(session, closeStatus);
            }

            /**
             * 接收消息
             *
             * @param session
             * @param message
             */
            @Override
            public void handleMessage(WebSocketSession session, WebSocketMessage<?> message) throws Exception {
                List<String> payloads = Arrays.asList(StrUtil.split(message.getPayload().toString(), "\n\n"));
                if (CollectionUtil.isNotEmpty(payloads)) {
                    Map<String, String> head = parseSocketHeader(payloads.get(0));
                    String cmd = head.get(HEAD_CMD);

                    //客户端主动发送消息(订阅处理)
                    if (WSCommand.SEND.toString().equalsIgnoreCase(cmd)) {
                        String msg = payloads.get(1);
                        MonitorCommandDTO command = JSONUtil.toBean(msg, MonitorCommandDTO.class);
                        command.setSessionId(session.getId());
                        monitorWork.doWork(command);
                    }
                    //订阅
                    if (WSCommand.SUBSCRIBE.toString().equalsIgnoreCase(cmd)) {
                        String topics = head.get("destination");
                        if (topics != null) {
                            topics = StrUtil.removeSuffix(topics.toLowerCase(), StrUtil.SLASH);
                            switch (topics) {
                                case SocketTopics.BOX_COUNT_RANK:
                                case SocketTopics.BOX_TOTAL_COUNT:
                                case SocketTopics.HEATMAP:
                                    CompletableFuture.runAsync(() -> {
                                        try {
                                            Thread.sleep(200);
                                            monitorWork.doWordIndexTopic();
                                        } catch (InterruptedException e) {
                                            e.printStackTrace();
                                        }
                                    });
                                    break;
                            }
                        }
                    }
                }
                super.handleMessage(session, message);
            }
        };
    }

    /**
     * 解析websocket请求头成map
     *
     * @param headerString
     * @return
     */
    private Map<String, String> parseSocketHeader(String headerString) {

        Map<String, String> map = new ConcurrentHashMap<>();

        List<String> headArr = StrUtil.split(headerString, '\n');
        int headSize = headArr.size();
        if (headSize == 0) {
            map.put(HEAD_CMD, StrUtil.EMPTY);
            return map;
        }

        map.put(HEAD_CMD, headArr.get(0));
        for (int i = 1; i < headSize; i++) {
            int indexColon = headArr.get(i).indexOf(StrUtil.COLON);
            map.put(
                    headArr.get(i).substring(0, indexColon).toLowerCase(),
                    headArr.get(i).substring(indexColon + 1)
            );
        }

        return map;
    }

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值