refactor: 实时在线用户统计代码重构优化

This commit is contained in:
ray
2024-08-26 00:14:17 +08:00
parent b2c6babae3
commit 19654de4de
4 changed files with 45 additions and 17 deletions

View File

@@ -4,12 +4,14 @@ import cn.hutool.core.util.StrUtil;
import cn.hutool.jwt.JWTPayload; import cn.hutool.jwt.JWTPayload;
import cn.hutool.jwt.JWTUtil; import cn.hutool.jwt.JWTUtil;
import com.youlai.system.common.constant.SecurityConstants; import com.youlai.system.common.constant.SecurityConstants;
import com.youlai.system.event.UserConnectionEvent;
import com.youlai.system.service.WebsocketService; import com.youlai.system.service.WebsocketService;
import groovy.lang.Lazy; import groovy.lang.Lazy;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpHeaders; import org.springframework.http.HttpHeaders;
import org.springframework.messaging.Message; import org.springframework.messaging.Message;
@@ -36,8 +38,11 @@ import org.springframework.web.socket.config.annotation.WebSocketMessageBrokerCo
@Slf4j @Slf4j
public class WebSocketConfig implements WebSocketMessageBrokerConfigurer { public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {
@Autowired private final ApplicationEventPublisher eventPublisher;
private WebsocketService websocketService;
public WebSocketConfig(ApplicationEventPublisher eventPublisher) {
this.eventPublisher = eventPublisher;
}
/** /**
* 注册一个端点,客户端通过这个端点进行连接 * 注册一个端点,客户端通过这个端点进行连接
*/ */
@@ -88,13 +93,13 @@ public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {
String username = JWTUtil.parseToken(bearerToken).getPayloads().getStr(JWTPayload.SUBJECT); String username = JWTUtil.parseToken(bearerToken).getPayloads().getStr(JWTPayload.SUBJECT);
if (StrUtil.isNotBlank(username)) { if (StrUtil.isNotBlank(username)) {
accessor.setUser(() -> username); accessor.setUser(() -> username);
websocketService.addUser(username); eventPublisher.publishEvent(new UserConnectionEvent(this, username, true));
} }
} }
} else if (StompCommand.DISCONNECT.equals(accessor.getCommand())) { } else if (StompCommand.DISCONNECT.equals(accessor.getCommand())) {
if (accessor.getUser() != null) { if (accessor.getUser() != null) {
String username = accessor.getUser().getName(); String username = accessor.getUser().getName();
websocketService.removeUser(username); eventPublisher.publishEvent(new UserConnectionEvent(this, username, false));
} }
} }
} }

View File

@@ -0,0 +1,16 @@
package com.youlai.system.event;
import lombok.Getter;
import org.springframework.context.ApplicationEvent;
@Getter
public class UserConnectionEvent extends ApplicationEvent {
private final String username;
private final boolean connected;
public UserConnectionEvent(Object source, String username, boolean connected) {
super(source);
this.username = username;
this.connected = connected;
}
}

View File

@@ -6,5 +6,4 @@ public interface WebsocketService {
void removeUser(String username) ; void removeUser(String username) ;
int getOnlineUserCount() ;
} }

View File

@@ -1,9 +1,10 @@
package com.youlai.system.service.impl; package com.youlai.system.service.impl;
import com.youlai.system.event.UserConnectionEvent;
import com.youlai.system.service.WebsocketService; import com.youlai.system.service.WebsocketService;
import groovy.lang.Lazy;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired; import lombok.extern.slf4j.Slf4j;
import org.springframework.context.event.EventListener;
import org.springframework.messaging.simp.SimpMessagingTemplate; import org.springframework.messaging.simp.SimpMessagingTemplate;
import org.springframework.scheduling.annotation.Scheduled; import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
@@ -12,13 +13,13 @@ import java.util.Set;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
@Service @Service
@Slf4j
@RequiredArgsConstructor
public class WebsocketServiceImpl implements WebsocketService { public class WebsocketServiceImpl implements WebsocketService {
@Lazy private final SimpMessagingTemplate messagingTemplate;
@Autowired
private SimpMessagingTemplate messagingTemplate;
private static final Set<String> onlineUsers = ConcurrentHashMap.newKeySet(); private final Set<String> onlineUsers = ConcurrentHashMap.newKeySet();
@Override @Override
public void addUser(String username) { public void addUser(String username) {
@@ -30,15 +31,22 @@ public class WebsocketServiceImpl implements WebsocketService {
onlineUsers.remove(username); onlineUsers.remove(username);
} }
@Override @EventListener
public int getOnlineUserCount() { public void handleUserConnectionEvent(UserConnectionEvent event) {
return onlineUsers.size(); String username = event.getUsername();
if (event.isConnected()) {
onlineUsers.add(username);
log.info("User connected: {}", username);
} else {
onlineUsers.remove(username);
log.info("User disconnected: {}", username);
}
// 推送在线用户人数
messagingTemplate.convertAndSend("/topic/onlineUserCount", onlineUsers.size());
} }
@Scheduled(fixedRate = 5000) @Scheduled(fixedRate = 5000)
public void sendOnlineUserCount() { public void sendOnlineUserCount() {
int onlineUserCount = this.getOnlineUserCount(); messagingTemplate.convertAndSend("/topic/onlineUserCount", onlineUsers.size());
messagingTemplate.convertAndSend("/topic/onlineUserCount", onlineUserCount);
} }
} }