From 9f5b9f158f72a25bb057cb5d724084139a98ea1b Mon Sep 17 00:00:00 2001 From: CaptainB Date: Wed, 24 Aug 2022 19:31:52 +0800 Subject: [PATCH] =?UTF-8?q?refactor(=E6=B6=88=E6=81=AF=E9=80=9A=E7=9F=A5):?= =?UTF-8?q?=20=E7=AB=99=E5=86=85=E6=B6=88=E6=81=AF=E5=88=B7=E6=96=B0?= =?UTF-8?q?=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --bug=1016011 --user=刘瑞斌 【消息通知】执行接口case时有时收到多条系统站内通知,有时不会弹出站内通知 https://www.tapd.cn/55049933/s/1233494 --- .../websocket/NotificationWebSocket.java | 81 ++++++++++++------- .../components/notice/Notification.vue | 3 + 2 files changed, 53 insertions(+), 31 deletions(-) diff --git a/backend/src/main/java/io/metersphere/websocket/NotificationWebSocket.java b/backend/src/main/java/io/metersphere/websocket/NotificationWebSocket.java index 87779101ca..061a878a4c 100644 --- a/backend/src/main/java/io/metersphere/websocket/NotificationWebSocket.java +++ b/backend/src/main/java/io/metersphere/websocket/NotificationWebSocket.java @@ -7,12 +7,16 @@ import io.metersphere.commons.utils.LogUtil; import io.metersphere.notice.service.NotificationService; import lombok.Builder; import lombok.Data; +import org.apache.commons.collections4.CollectionUtils; import org.springframework.stereotype.Component; import javax.annotation.Resource; import javax.websocket.*; import javax.websocket.server.PathParam; import javax.websocket.server.ServerEndpoint; +import java.io.IOException; +import java.util.HashSet; +import java.util.Set; import java.util.Timer; import java.util.TimerTask; import java.util.concurrent.ConcurrentHashMap; @@ -21,7 +25,8 @@ import java.util.concurrent.ConcurrentHashMap; @Component public class NotificationWebSocket { private static NotificationService notificationService; - private static ConcurrentHashMap refreshTasks = new ConcurrentHashMap<>(); + private static final ConcurrentHashMap refreshTasks = new ConcurrentHashMap<>(); + private static final ConcurrentHashMap> sessionMap = new ConcurrentHashMap<>(); @Resource public void setNotificationService(NotificationService notificationService) { @@ -33,21 +38,44 @@ public class NotificationWebSocket { */ @OnOpen public void onOpen(@PathParam("userId") String userId, Session session) { - Timer timer = new Timer(true); - NotificationCenter task = new NotificationCenter(session, userId); + LogUtil.info("建立一个socket链接: {} - {}", userId, session.getId()); + Timer timer = refreshTasks.get(userId); + if (timer != null) { + timer.cancel(); + } + timer = new Timer(true); + NotificationCenter task = new NotificationCenter(userId); timer.schedule(task, 0, 10 * 1000); - refreshTasks.putIfAbsent(session, timer); + refreshTasks.put(userId, timer); + + Set sessions = sessionMap.getOrDefault(userId, new HashSet<>()); + sessions.add(session); + sessionMap.put(userId, sessions); + + LogUtil.info("在线socket链接: {}, size: {}", userId, sessions.size()); } /** * 连接关闭的操作 */ @OnClose - public void onClose(Session session) { - Timer timer = refreshTasks.get(session); - if (timer != null) { - timer.cancel(); - refreshTasks.remove(session); + public void onClose(@PathParam("userId") String userId, Session session) { + // 删除当前session + Set sessions = sessionMap.get(userId); + if (CollectionUtils.isNotEmpty(sessions)) { + LogUtil.info("剔除一个socket链接: {} - {}", userId, session.getId()); + sessions.remove(session); + } + + // 没有在线用户了 + if (CollectionUtils.isEmpty(sessions)) { + LogUtil.info("关闭socket: {} ", userId); + + Timer timer = refreshTasks.get(userId); + if (timer != null) { + timer.cancel(); + refreshTasks.remove(userId); + } } } @@ -56,21 +84,7 @@ public class NotificationWebSocket { */ @OnMessage public void onMessage(@PathParam("userId") String userId, Session session, String message) { - int refreshTime = 10; - try { - refreshTime = Integer.parseInt(message); - } catch (Exception e) { - } - try { - Timer timer = refreshTasks.get(session); - timer.cancel(); - - Timer newTimer = new Timer(true); - newTimer.schedule(new NotificationCenter(session, userId), 0, refreshTime * 1000L); - refreshTasks.put(session, newTimer); - } catch (Exception e) { - LogUtil.error(e.getMessage(), e); - } + LogUtil.info(message); } /** @@ -83,20 +97,15 @@ public class NotificationWebSocket { } public static class NotificationCenter extends TimerTask { - private Session session; private String userId; - NotificationCenter(Session session, String userId) { - this.session = session; + NotificationCenter(String userId) { this.userId = userId; } @Override public void run() { try { - if (!session.isOpen()) { - return; - } Notification notification = new Notification(); notification.setReceiver(userId); notification.setStatus(NotificationConstants.Status.UNREAD.name()); @@ -105,7 +114,17 @@ public class NotificationWebSocket { .count(count) .now(System.currentTimeMillis()) .build(); - session.getBasicRemote().sendText(JSON.toJSONString(message)); + + Set sessions = sessionMap.get(userId); + if (CollectionUtils.isNotEmpty(sessions)) { + sessions.forEach(session -> { + try { + session.getBasicRemote().sendText(JSON.toJSONString(message)); + } catch (IOException e) { + LogUtil.error(e.getMessage(), e); + } + }); + } } catch (Exception e) { LogUtil.error(e.getMessage(), e); } diff --git a/frontend/src/business/components/notice/Notification.vue b/frontend/src/business/components/notice/Notification.vue index d4a3cd50e7..fcc3588051 100644 --- a/frontend/src/business/components/notice/Notification.vue +++ b/frontend/src/business/components/notice/Notification.vue @@ -84,6 +84,9 @@ export default { } } }, + beforeDestroy() { + this.websocket.close(); + }, methods: { getUserList() { this.$get('/user/ws/current/member/list', response => {