@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;
}
}
websocket Messgae handle
最新推荐文章于 2025-03-19 13:12:18 发布
该博客主要介绍了WebSocket连接的管理和消息处理。当WebSocket连接建立和关闭时,它会进行相应的设备状态更新和Redis操作。此外,它还解析并处理接收到的消息,包括订阅和客户端主动发送的消息。在接收到消息后,会调用`monitorWork`进行工作调度。
2万+

被折叠的 条评论
为什么被折叠?



