feat: move the old chess controller to this branch

This commit is contained in:
wzp 2024-12-24 18:34:29 +08:00
parent 374271bd47
commit 73d061979b
24 changed files with 733 additions and 1 deletions

View File

@ -28,7 +28,8 @@ repositories {
dependencies {
implementation("org.springframework.boot:spring-boot-starter-actuator")
implementation("org.mmga:make-minecraft-great-again-spring-boot-starter:0.0.5-20241224.081553-6")
implementation("org.springframework.boot:spring-boot-starter-websocket")
implementation("org.mmga:make-minecraft-great-again-spring-boot-starter:0.0.5-20241224.092835-8")
implementation("com.mybatis-flex:mybatis-flex-spring-boot-starter:1.10.2")
annotationProcessor("com.mybatis-flex:mybatis-flex-processor:1.10.2")
// https://mvnrepository.com/artifact/commons-codec/commons-codec

View File

@ -5,8 +5,10 @@ import com.mybatisflex.core.audit.ConsoleMessageCollector;
import com.mybatisflex.core.audit.MessageCollector;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.socket.config.annotation.EnableWebSocket;
@SpringBootApplication
@EnableWebSocket
public class ClubApplication {
public static void main(String[] args) {

View File

@ -0,0 +1,13 @@
package org.blue.club.configuration;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.socket.server.standard.ServerEndpointExporter;
@Configuration
public class WebSocketConfiguration {
@Bean
public ServerEndpointExporter serverEndpointExporter() {
return new ServerEndpointExporter();
}
}

View File

@ -0,0 +1,275 @@
package org.blue.club.controller;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONException;
import com.alibaba.fastjson2.JSONObject;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.annotation.Nullable;
import jakarta.websocket.*;
import jakarta.websocket.server.PathParam;
import jakarta.websocket.server.ServerEndpoint;
import lombok.NoArgsConstructor;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.blue.club.dao.UserDao;
import org.blue.club.entities.dto.chess.Room;
import org.blue.club.entities.dto.chess.packet.*;
import org.blue.club.entities.dto.chess.packet.request.*;
import org.blue.club.entities.dto.user.User;
import org.blue.club.utils.WebSocketUtils;
import org.mmga.spring.boot.starter.componet.JwtUtils;
import org.mmga.spring.boot.starter.utils.VoUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import java.lang.reflect.Field;
import java.nio.ByteBuffer;
import java.time.Instant;
import java.time.temporal.ChronoUnit;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentLinkedQueue;
@Slf4j
@Tag(name = "五子棋", description = "五子棋相关websocket接口")
@ServerEndpoint("/chess/{token}")
@Component
@NoArgsConstructor
public class ChessController {
private static final ConcurrentHashMap<String, Session> sessions = new ConcurrentHashMap<>();
private static final ConcurrentHashMap<String, User> users = new ConcurrentHashMap<>();
private static final ConcurrentHashMap<UUID, Room> rooms = new ConcurrentHashMap<>();
private static final ConcurrentHashMap<Session, Boolean> pingPong = new ConcurrentHashMap<>();
private static JwtUtils jwtUtils;
private static VoUtils voUtils;
private static UserDao userDao;
@Autowired
public void setVoUtils(VoUtils voUtils) {
ChessController.voUtils = voUtils;
}
@Autowired
public void setUserDao(UserDao userDao) {
ChessController.userDao = userDao;
}
@Autowired
public void setJwtUtils(JwtUtils jwtUtils) {
ChessController.jwtUtils = jwtUtils;
}
private final Queue<String> messageQueue = new ConcurrentLinkedQueue<>();
private boolean isLogin = false;
@SneakyThrows
@OnOpen
public void onOpen(Session session, @PathParam("token") String token) {
isLogin = false;
Optional<Long> i = jwtUtils.verifyToken(token);
if (i.isEmpty()) {
WebSocketUtils.sendPacket(new ErrorPacket("token验证失败"), session);
log.info("closed by token verifier");
session.close(new CloseReason(CloseReason.CloseCodes.CANNOT_ACCEPT, "token验证失败"));
messageQueue.clear();
return;
}
String sessionId = session.getId();
User user = voUtils.vo2DtoSafe(userDao.selectOneWithRelationsById(i.get()), User.class);
WebSocketUtils.sendPacket(new UserInfoPacket(user), session);
String existsUser = null;
long id = user.getId();
for (Map.Entry<String, User> entry : users.entrySet()) {
User value = entry.getValue();
if (value.getId() == id) {
existsUser = entry.getKey();
break;
}
}
users.put(sessionId, user);
sessions.put(sessionId, session);
isLogin = true;
if (existsUser != null) {
users.remove(existsUser);
Room roomByPlayer = getRoomByPlayer(existsUser);
if (roomByPlayer != null) {
roomByPlayer.replace(existsUser, session);
WebSocketUtils.sendPacket(new PlayerSideAllocationPacket(roomByPlayer.isPlayerWhite(existsUser)), session);
WebSocketUtils.sendPacket(roomByPlayer.getRoomInfo(users), session);
}
Session remove = sessions.remove(existsUser);
log.info("session closed by another session");
remove.close(new CloseReason(CloseReason.CloseCodes.NOT_CONSISTENT, "你的账号已在别处登录"));
}
for (String s : messageQueue) {
this.onMessage(s, session);
}
}
@OnMessage
public void onPong(PongMessage pongMessage, Session session) {
ByteBuffer applicationData = pongMessage.getApplicationData();
ByteBuf byteBuf = Unpooled.copiedBuffer(applicationData);
long l = System.currentTimeMillis() - byteBuf.readLong();
log.info("client sent pong response, latency is {}ms", l);
pingPong.put(session, true);
}
@OnMessage
public void onMessage(String message, Session session) {
if (!isLogin) {
messageQueue.add(message);
return;
}
try {
JSONObject jsonObject = JSON.parseObject(message);
String packetName = jsonObject.getString("name");
if (packetName == null) {
WebSocketUtils.sendPacket(new ErrorPacket("包内缺少name字段"), session);
}
Object response = handleMessage(jsonObject, packetName, session);
if (response != null) {
WebSocketUtils.sendPacket(response, packetName, session);
}
} catch (JSONException e) {
WebSocketUtils.sendPacket(new ErrorPacket("JSON格式错误"), session);
}
}
@Nullable
public Object handleMessage(JSONObject object, String packetName, Session session) {
if (packetName == null) return new ErrorPacket("错误的请求类型");
try {
Class<?> packetType = Class.forName("org.blue.club.entities.dto.chess.packet.request." + packetName + "Request");
JSONObject payloadJson = object.getJSONObject("payload");
if (payloadJson == null) {
Field[] declaredFields = packetType.getDeclaredFields();
if (declaredFields.length == 0) {
payloadJson = new JSONObject();
}
}
if (payloadJson == null) return new ErrorPacket("请求类型参数错误!");
Object payload;
try {
payload = payloadJson.to(packetType);
} catch (Exception e) {
return new ErrorPacket("请求payload解析失败");
}
if (payload == null) return null;
return handlePacket(payload, session);
} catch (ClassNotFoundException e) {
return new ErrorPacket("错误的请求类型");
}
}
public Object handlePacket(Object payload, Session session) {
String sessionId = session.getId();
if (payload instanceof PlayerJoinRequest joinRequest) {
Room roomByPlayer = getRoomByPlayer(sessionId);
if (roomByPlayer != null) return new ErrorPacket("你已经加入过一个房间了");
Room room = rooms.get(joinRequest.roomId());
if (room == null) return new ErrorPacket("未知的房间");
Optional<String> join = room.join(session, users.get(sessionId));
if (join.isPresent()) return new ErrorPacket(join.get());
room.broadcast(room.getRoomInfo(users));
}
if (payload instanceof RoomListRequest) {
Collection<Room> values = rooms.values();
return new RoomListPacket(values);
}
if (payload instanceof CreateRoomRequest) {
Room room = new Room();
UUID roomId = room.getId();
rooms.put(roomId, room);
return new RoomCreatedPacket(roomId);
}
if (payload instanceof PlaceChessPieceRequest placeChessPieceRequest) {
int x = placeChessPieceRequest.x();
int y = placeChessPieceRequest.y();
Room roomByPlayer = getRoomByPlayer(sessionId);
if (roomByPlayer == null) return new ErrorPacket("你还没加入房间呢");
Optional<String> s = roomByPlayer.downPiece(x, y, sessionId);
if (s.isPresent()) return new ErrorPacket(s.get());
roomByPlayer.broadcast(roomByPlayer.getRoomInfo(users));
Optional<Room.WinInfo> winInfo = roomByPlayer.isWin();
winInfo.ifPresent(info -> {
roomByPlayer.broadcast(new HasPlayerWinPacket(info));
if (info.isWhite()) {
WebSocketUtils.sendPacketIfPossible(new PlayerWinPacket(), roomByPlayer.getWhiteSession());
WebSocketUtils.sendPacketIfPossible(new PlayerLosePacket(), roomByPlayer.getBlackSession());
} else {
WebSocketUtils.sendPacketIfPossible(new PlayerWinPacket(), roomByPlayer.getBlackSession());
WebSocketUtils.sendPacketIfPossible(new PlayerLosePacket(), roomByPlayer.getWhiteSession());
}
roomByPlayer.setState(Room.RoomState.FINISHED);
roomByPlayer.broadcast(roomByPlayer.getRoomInfo(users));
});
}
if (payload instanceof ResetRoomRequest) {
Room roomByPlayer = getRoomByPlayer(sessionId);
if (roomByPlayer == null) return new ErrorPacket("你还没加入房间呢");
roomByPlayer.requestRestart(session);
roomByPlayer.broadcast(roomByPlayer.getRoomInfo(users));
}
return null;
}
@Nullable
private static Room getRoomByPlayer(String id) {
for (Room value : rooms.values()) {
if (value.isIn(id)) return value;
}
return null;
}
public static void staticOnClose(Session session) {
String sessionId = session.getId();
Room roomByPlayer = getRoomByPlayer(sessionId);
if (roomByPlayer != null) {
roomByPlayer.leave(session);
roomByPlayer.broadcast(roomByPlayer.getRoomInfo(users));
}
log.info("session closed {}", sessionId);
sessions.remove(sessionId);
users.remove(sessionId);
pingPong.remove(session);
}
@OnClose
public void onClose(Session session) {
staticOnClose(session);
}
@SneakyThrows
@Scheduled(fixedDelay = 10000)
public static void connectionManager() {
for (Session value : sessions.values()) {
if (!pingPong.getOrDefault(value, true)) {
log.info("closed by connectionManager");
if (value.isOpen()) {
value.close(new CloseReason(CloseReason.CloseCodes.CLOSED_ABNORMALLY, "链接延迟过高"));
continue;
}
staticOnClose(value);
continue;
}
pingPong.put(value, false);
log.info("send ping to session {}", value.getId());
value.getAsyncRemote().sendPing(Unpooled.buffer().writeLong(System.currentTimeMillis()).nioBuffer());
}
Instant instant = new Date().toInstant();
Instant before10Min = instant.plus(-10, ChronoUnit.MINUTES);
rooms.entrySet().stream()
.filter(e -> e.getValue().getState().equals(Room.RoomState.CREATED))
.filter(e -> e.getValue().getLastStateChange().toInstant().isBefore(before10Min))
.map(Map.Entry::getKey)
.forEach(rooms::remove);
rooms.values().forEach(Room::tryClean);
}
}

View File

@ -0,0 +1,234 @@
package org.blue.club.entities.dto.chess;
import com.alibaba.fastjson2.annotation.JSONField;
import jakarta.websocket.Session;
import lombok.AccessLevel;
import lombok.Data;
import lombok.RequiredArgsConstructor;
import lombok.Setter;
import org.blue.club.entities.dto.chess.packet.PlayerJoinRoomPacket;
import org.blue.club.entities.dto.chess.packet.PlayerLeavePacket;
import org.blue.club.entities.dto.chess.packet.PlayerSideAllocationPacket;
import org.blue.club.entities.dto.chess.packet.RoomInfoPacket;
import org.blue.club.entities.dto.user.User;
import org.blue.club.utils.WebSocketUtils;
import java.util.*;
@Data
public class Room {
private UUID id;
private RoomState state;
@JSONField(serialize = false, deserialize = false)
private Session whiteSession;
@JSONField(serialize = false, deserialize = false)
private Session blackSession;
@JSONField(serialize = false, deserialize = false)
private byte[][] pieces;
private boolean isWhiteAcceptRestart;
private boolean isBlackAcceptRestart;
private boolean canWhiteDown;
@Setter(value = AccessLevel.PRIVATE)
private Date lastStateChange;
public Room() {
this.id = UUID.randomUUID();
this.state = RoomState.CREATED;
this.lastStateChange = new Date();
resetPieces();
}
public void setState(RoomState state) {
if (state == this.state) return;
this.state = state;
this.lastStateChange = new Date();
}
public void resetPieces() {
this.canWhiteDown = false;
this.pieces = new byte[16][16];
for (int i = 0; i < 16; i++) {
for (int j = 0; j < 16; j++) {
this.pieces[i][j] = -1;
}
}
isWhiteAcceptRestart = false;
isBlackAcceptRestart = false;
}
public boolean isFull() {
return Objects.nonNull(this.whiteSession) && Objects.nonNull(this.blackSession);
}
public Optional<String> join(Session session, User user) {
if (this.getState() == RoomState.GAMING) {
return Optional.of("你所加入的房间正在游戏!");
}
if (this.isFull()) {
return Optional.of("所加入的房间已满");
}
if (Objects.nonNull(this.whiteSession)) {
WebSocketUtils.sendPacket(new PlayerSideAllocationPacket(false), session);
WebSocketUtils.sendPacketIfPossible(new PlayerJoinRoomPacket(user, this), whiteSession);
this.blackSession = session;
} else {
WebSocketUtils.sendPacket(new PlayerSideAllocationPacket(true), session);
WebSocketUtils.sendPacketIfPossible(new PlayerJoinRoomPacket(user, this), blackSession);
this.whiteSession = session;
}
if (this.isFull()) {
this.setState(RoomState.GAMING);
} else {
this.setState(RoomState.WAITING);
}
return Optional.empty();
}
public void leave(Session session) {
String sessionId = session.getId();
if (Objects.nonNull(this.blackSession) && this.blackSession.getId().equals(sessionId)) {
WebSocketUtils.sendPacketIfPossible(new PlayerLeavePacket(sessionId), whiteSession);
this.blackSession = null;
this.setState(RoomState.WAITING);
}
if (Objects.nonNull(this.whiteSession) && this.whiteSession.getId().equals(sessionId)) {
WebSocketUtils.sendPacketIfPossible(new PlayerLeavePacket(sessionId), blackSession);
this.whiteSession = null;
this.setState(RoomState.WAITING);
}
if (Objects.isNull(this.blackSession) && Objects.isNull(this.whiteSession)) {
this.setState(RoomState.CREATED);
}
}
public RoomInfoPacket getRoomInfo(Map<String, User> users) {
Session whiteSession = this.getWhiteSession();
Session blackSession = this.getBlackSession();
User whiteUser = whiteSession != null ? users.get(whiteSession.getId()) : null;
User blackUser = blackSession != null ? users.get(blackSession.getId()) : null;
return new RoomInfoPacket(this.id, whiteUser, blackUser, this.state, pieces, this.isWhiteAcceptRestart, this.isBlackAcceptRestart, this.canWhiteDown);
}
public void broadcast(Object packet) {
if (packet == null) return;
WebSocketUtils.sendPacketIfPossible(packet, whiteSession);
WebSocketUtils.sendPacketIfPossible(packet, blackSession);
}
public boolean isIn(String sessionId) {
return (Objects.nonNull(whiteSession) && whiteSession.getId().equals(sessionId)) || (Objects.nonNull(blackSession) && blackSession.getId().equals(sessionId));
}
public Optional<String> downPiece(int x, int y, String sessionId) {
if (!this.getState().equals(RoomState.GAMING)) return Optional.of("游戏暂未开始!");
byte originalValue = this.pieces[y][x];
if (originalValue != -1) return Optional.of("此位置已落子!");
if (whiteSession.getId().equals(sessionId)) {
if (!canWhiteDown) return Optional.of("请等待对手落子");
canWhiteDown = false;
this.pieces[y][x] = 1;
} else {
if (canWhiteDown) return Optional.of("请等待对手落子");
canWhiteDown = true;
this.pieces[y][x] = 0;
}
return Optional.empty();
}
public Optional<WinInfo> isWin() {
for (int y = 0; y < 16; y++) {
for (int x = 0; x < 16; x++) {
byte startPointType = this.pieces[y][x];
if (startPointType == -1) continue;
for (Faces value : Faces.values()) {
boolean facePossible = true;
for (int i = 1; i < 5; i++) {
int totalXDelta = value.xDelta * i;
int totalYDelta = value.yDelta * i;
int fullyX = x + totalXDelta;
int fullyY = y + totalYDelta;
if (fullyX < 0 || fullyX > 15 || fullyY < 0 || fullyY > 15) {
facePossible = false;
break;
}
if (this.pieces[fullyY][fullyX] != startPointType) {
facePossible = false;
break;
}
}
if (!facePossible) continue;
return Optional.of(new WinInfo(value, x, y, startPointType == 1));
}
}
}
return Optional.empty();
}
public void requestRestart(Session session) {
String sessionId = session.getId();
if (whiteSession == null || sessionId.equals(whiteSession.getId())) {
isWhiteAcceptRestart = true;
}
if (blackSession == null || sessionId.equals(blackSession.getId())) {
isBlackAcceptRestart = true;
}
if (isBlackAcceptRestart && isWhiteAcceptRestart) {
this.resetPieces();
if (whiteSession == null || blackSession == null) {
this.setState(RoomState.WAITING);
return;
}
this.setState(RoomState.GAMING);
}
}
public void replace(String existsUser, Session session) {
if (Objects.nonNull(this.whiteSession) && whiteSession.getId().equals(existsUser)) {
whiteSession = session;
}
if (Objects.nonNull(this.blackSession) && blackSession.getId().equals(existsUser)) {
blackSession = session;
}
}
public boolean isPlayerWhite(String sessionId) {
return sessionId.equals(whiteSession.getId());
}
public void tryClean() {
if (whiteSession != null) {
if (!whiteSession.isOpen()) {
this.leave(whiteSession);
}
}
if (blackSession != null) {
if (!blackSession.isOpen()) {
this.leave(blackSession);
}
}
}
public enum RoomState {
CREATED,
WAITING,
GAMING,
FINISHED
}
@RequiredArgsConstructor
public enum Faces {
UP(0, -1),
UP_RIGHT(1, -1),
RIGHT(1, 0),
DOWN_RIGHT(1, 1),
DOWN(0, 1),
DOWN_LEFT(-1, 1),
LEFT(-1, 0),
UP_LEFT(-1, -1);
public final int xDelta, yDelta;
}
public record WinInfo(Faces face, int originalX, int originalY, boolean isWhite) {
}
}

View File

@ -0,0 +1,32 @@
package org.blue.club.entities.dto.chess.packet;
import jakarta.annotation.Nullable;
import lombok.Data;
import lombok.NonNull;
@Data
public class BaseWebSocketPacket {
private String name;
private Object payload;
@Nullable
private String originalPacketName;
public BaseWebSocketPacket(Object payload) {
Class<?> aClass = payload.getClass();
this.name = aClass.getSimpleName().replace("Packet", "");
this.payload = payload;
}
public BaseWebSocketPacket(Object payload, @NonNull String originalPacketName) {
this(payload);
this.originalPacketName = originalPacketName;
}
public static BaseWebSocketPacket of(Object payload) {
return new BaseWebSocketPacket(payload);
}
public static BaseWebSocketPacket of(Object packet, @NonNull String originalPacketName) {
return new BaseWebSocketPacket(packet, originalPacketName);
}
}

View File

@ -0,0 +1,4 @@
package org.blue.club.entities.dto.chess.packet;
public record ErrorPacket(String reason) {
}

View File

@ -0,0 +1,6 @@
package org.blue.club.entities.dto.chess.packet;
import org.blue.club.entities.dto.chess.Room;
public record HasPlayerWinPacket(Room.WinInfo winInfo) {
}

View File

@ -0,0 +1,7 @@
package org.blue.club.entities.dto.chess.packet;
import org.blue.club.entities.dto.chess.Room;
import org.blue.club.entities.dto.user.User;
public record PlayerJoinRoomPacket(User user, Room room) {
}

View File

@ -0,0 +1,4 @@
package org.blue.club.entities.dto.chess.packet;
public record PlayerLeavePacket(String player) {
}

View File

@ -0,0 +1,4 @@
package org.blue.club.entities.dto.chess.packet;
public record PlayerLosePacket() {
}

View File

@ -0,0 +1,4 @@
package org.blue.club.entities.dto.chess.packet;
public record PlayerSideAllocationPacket(boolean isWhite) {
}

View File

@ -0,0 +1,4 @@
package org.blue.club.entities.dto.chess.packet;
public record PlayerWinPacket() {
}

View File

@ -0,0 +1,6 @@
package org.blue.club.entities.dto.chess.packet;
import java.util.UUID;
public record RoomCreatedPacket(UUID roomId) {
}

View File

@ -0,0 +1,10 @@
package org.blue.club.entities.dto.chess.packet;
import org.blue.club.entities.dto.chess.Room;
import org.blue.club.entities.dto.user.User;
import java.util.UUID;
public record RoomInfoPacket(UUID roomId, User whiteUser, User blackUser, Room.RoomState state, byte[][] pieces,
boolean whiteRequestRestart, boolean blackRequestRestart, boolean canWhiteDown) {
}

View File

@ -0,0 +1,8 @@
package org.blue.club.entities.dto.chess.packet;
import org.blue.club.entities.dto.chess.Room;
import java.util.Collection;
public record RoomListPacket(Collection<Room> rooms) {
}

View File

@ -0,0 +1,6 @@
package org.blue.club.entities.dto.chess.packet;
import org.blue.club.entities.dto.user.User;
public record UserInfoPacket(User user) {
}

View File

@ -0,0 +1,4 @@
package org.blue.club.entities.dto.chess.packet.request;
public record CreateRoomRequest() {
}

View File

@ -0,0 +1,4 @@
package org.blue.club.entities.dto.chess.packet.request;
public record PlaceChessPieceRequest(int x, int y) {
}

View File

@ -0,0 +1,6 @@
package org.blue.club.entities.dto.chess.packet.request;
import java.util.UUID;
public record PlayerJoinRequest(UUID roomId) {
}

View File

@ -0,0 +1,4 @@
package org.blue.club.entities.dto.chess.packet.request;
public record ResetRoomRequest() {
}

View File

@ -0,0 +1,4 @@
package org.blue.club.entities.dto.chess.packet.request;
public record RoomListRequest() {
}

View File

@ -0,0 +1,56 @@
package org.blue.club.schedule;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.blue.club.dao.redis.AvatarOperationDao;
import org.blue.club.dao.redis.VerifyDao;
import org.blue.club.entities.vo.VerifyVo;
import org.blue.club.entities.vo.data.AvatarTmpVo;
import org.blue.club.utils.iop.FileUtils;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import java.io.File;
import java.time.Instant;
import java.time.temporal.ChronoUnit;
import java.util.Date;
@Slf4j
@Component
@RequiredArgsConstructor
public class RemoveExpireDataSchedule {
private final AvatarOperationDao avatarDao;
private final File tmpFolder;
private final VerifyDao verifyDao;
private final FileUtils fileUtils;
@Scheduled(fixedDelay = 1000)
public void removeTempAvatar() {
Instant now = Instant.now();
for (AvatarTmpVo avatarTmpVo : avatarDao.findAll()) {
Date time = avatarTmpVo.createTime();
Instant instant = time.toInstant();
Instant expireTime = instant.plus(15, ChronoUnit.MINUTES);
if (expireTime.isAfter(now)) {
String s = avatarTmpVo.operationCode();
File deleteFile = new File(tmpFolder, s);
if (deleteFile.exists()) {
fileUtils.tryDeleteOrDeleteOnExit(deleteFile);
}
avatarDao.delete(avatarTmpVo);
}
}
}
@Scheduled(fixedDelay = 1000)
public void removeExpiredVerify() {
Instant now = Instant.now();
for (VerifyVo verifyVo : verifyDao.findAll()) {
Instant instant = verifyVo.createTime().toInstant();
Instant expireTime = instant.plus(15, ChronoUnit.MINUTES);
if (expireTime.isAfter(now)) {
verifyDao.delete(verifyVo);
}
}
}
}

View File

@ -0,0 +1,34 @@
package org.blue.club.utils;
import com.alibaba.fastjson2.JSONObject;
import jakarta.annotation.Nullable;
import jakarta.websocket.Session;
import lombok.NonNull;
import lombok.SneakyThrows;
import org.blue.club.entities.dto.chess.packet.BaseWebSocketPacket;
import java.util.Objects;
public class WebSocketUtils {
@SneakyThrows
public static void sendJsonMessage(@NonNull JSONObject message, @NonNull Session session) {
session.getBasicRemote().sendText(message.toJSONString());
}
public static void sendMessage(@NonNull Object object, @NonNull Session session) {
sendJsonMessage(JSONObject.from(object), session);
}
public static void sendPacket(@NonNull Object packet, @NonNull Session session) {
sendMessage(BaseWebSocketPacket.of(packet), session);
}
public static void sendPacket(@NonNull Object packet, String originalPacketName, @NonNull Session session) {
sendMessage(BaseWebSocketPacket.of(packet, originalPacketName), session);
}
public static void sendPacketIfPossible(@NonNull Object packet, @Nullable Session session) {
if (Objects.isNull(session)) return;
sendPacket(packet, session);
}
}