Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

멀티게임 예외 추가 #59

Merged
merged 5 commits into from
Sep 27, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion src/main/java/kutaverse/game/taggame/domain/LifeStatus.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,7 @@

public enum LifeStatus {
TAGGED,
NOT_TAGGED
NOT_TAGGED,
//술래가 나간경우
TAGGER_OUT
}
10 changes: 8 additions & 2 deletions src/main/java/kutaverse/game/taggame/domain/TagGameUser.java
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,13 @@ public class TagGameUser {

private Double velocityZ;

public void confirmTagged() { this.lifeStatus = LifeStatus.TAGGED; }
public void confirmTagged() {
this.lifeStatus = LifeStatus.TAGGED;
}

public void confirmTaggerOut() {
this.lifeStatus = LifeStatus.TAGGER_OUT;
}

public static TagGameUser initTagGameUser(String userId, Role role, int userObjectNumber) {
return TagGameUser.builder()
Expand All @@ -58,7 +64,7 @@ public static TagGameUser initTagGameUser(String userId, Role role, int userObje


public TagGameUser update(TagGameUser tagGameUser) {
this.userObjectNumber=tagGameUser.getUserObjectNumber();
this.userObjectNumber = tagGameUser.getUserObjectNumber();
this.positionX = tagGameUser.getPositionX();
this.positionY = tagGameUser.getPositionY();
this.positionZ = tagGameUser.getPositionZ();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package kutaverse.game.taggame.repository;

import kutaverse.game.taggame.domain.Role;
import kutaverse.game.taggame.domain.TagGameUser;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Repository;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,4 +39,22 @@ public Mono<Void> initialize(List<Map.Entry<String, WebSocketSession>> players,
return Mono.never();
}

/**
* 유저가 접속이 끊기는 이벤트 처리
* @param userId 유저 id
* @return void
*/
public Mono<Void> closedUser(String userId) {
return tagGameUserRepository
.get(userId)
.flatMap(tagGameUser -> {
if(tagGameUser.getRole() == Role.TAGGER) {
tagGameUser.confirmTaggerOut();
return Mono.never();
}
tagGameUser.confirmTagged();
return Mono.never();
});
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ public void handler(Object object, WebSocketSession session) {
}

private void taggerWin(TagGameRoom tagGameRoom) {
tagGameRoom.getPlayers().forEach(player -> {
tagGameRoom.getPlayers().entrySet().forEach(player -> {
tagGameUserRepository.get(player.getKey())
.doOnNext( tagGameUser -> {
if(tagGameUser.getRole() == Role.TAGGER){
Expand All @@ -50,7 +50,7 @@ private void taggerWin(TagGameRoom tagGameRoom) {
}

private void playerWin(TagGameRoom tagGameRoom) {
tagGameRoom.getPlayers().forEach(player -> {
tagGameRoom.getPlayers().entrySet().forEach(player -> {
tagGameUserRepository.get(player.getKey())
.doOnNext( tagGameUser -> {
if(tagGameUser.getRole() == Role.PLAYER){
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,16 +17,20 @@
@RequiredArgsConstructor
@Slf4j
public class TagGameMatchingQueue {
//매칭큐
private static final ArrayDeque<Map.Entry<String, WebSocketSession>> queueing = new ArrayDeque<>();
//동일 유저 동시 요청에 대한 저장 map
private static final Map<String, WebSocketSession> sessionMap = new ConcurrentHashMap<>();
private static final Random random = new Random();
private final TagGameUserService tagGameUserService;

public static void addPlayer(String userId, WebSocketSession webSocketSession) {
//동일한 ID에 대한 요청이 세션 연결이 끊어진 상황인 경우 끊어진 요청을 제거한다.
if (sessionMap.containsKey(userId)) {
if(!sessionMap.get(userId).isOpen())
if (!sessionMap.get(userId).isOpen())
sessionMap.remove(userId);
}
//매칭에 넣는다.
if (!sessionMap.containsKey(userId)) {
queueing.offer(new AbstractMap.SimpleEntry<>(userId, webSocketSession));
sessionMap.put(userId, webSocketSession);
Expand Down Expand Up @@ -104,7 +108,8 @@ public void matchPlayers() throws InterruptedException {

}
}
public static void requeue(Map.Entry<String, WebSocketSession> player){

public static void requeue(Map.Entry<String, WebSocketSession> player) {
queueing.addFirst(player);
}

Expand All @@ -120,4 +125,16 @@ private Map.Entry<String, WebSocketSession> selectTagger(List<Map.Entry<String,

return players.get(randomIndex);
}

/**
* 연결이 끝어진 세션 회수 작업
*/
@Scheduled(fixedRate = 10000)
public void cleanSessionIfClosed() {
queueing.removeIf(webSocketSessionEntry -> !webSocketSessionEntry.getValue().isOpen());
for (Map.Entry<String, WebSocketSession> webSocketSessionEntry : sessionMap.entrySet()) {
if(!webSocketSessionEntry.getValue().isOpen())
sessionMap.remove(webSocketSessionEntry.getKey());
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,20 +6,29 @@

import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

@Getter
public class TagGameRoom {
private final String roomId;
private final List<Map.Entry<String, WebSocketSession>> players;
private final Map<String, WebSocketSession> players;
//private final List<Map.Entry<String, WebSocketSession>> players;
public TagGameRoom(String roomId, List<Map.Entry<String, WebSocketSession>> players) {
this.roomId = roomId;
this.players = players;
this.players = new ConcurrentHashMap<>();
for (Map.Entry<String, WebSocketSession> player : players) {
this.players.put(player.getKey(),player.getValue());
}

}

public void delete(){
for (Map.Entry<String, WebSocketSession> player : players) {
player.getValue().close().subscribe();
for (WebSocketSession webSocketSession : players.values()) {
webSocketSession.close().subscribe();
}
}

public void deleteUser(String userId){
players.remove(userId);
}
}
Original file line number Diff line number Diff line change
@@ -1,12 +1,24 @@
package kutaverse.game.websocket.taggame.util;

import kutaverse.game.websocket.taggame.util.TagGameRoom;

import kutaverse.game.taggame.domain.TagGameUser;
import kutaverse.game.taggame.repository.TagGameUserRepository;
import kutaverse.game.taggame.service.TagGameUserService;
import lombok.RequiredArgsConstructor;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import org.springframework.web.reactive.socket.WebSocketSession;

import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;

@Component
@RequiredArgsConstructor
public class TagGameRoomManager {

private final TagGameUserService tagGameUserService;

public static final Map<String, TagGameRoom> gameRooms = new ConcurrentHashMap<>();

public static void addGameRoom(TagGameRoom tagGameRoom) {
Expand All @@ -21,5 +33,19 @@ public static void deleteGameRoom(String roomId) {
gameRooms.remove(roomId);
}

@Scheduled(fixedRate = 10000)
public void cleanMemberIfClosed(){
for (TagGameRoom tagGameRoom : gameRooms.values()) {
Set<Map.Entry<String, WebSocketSession>> players = tagGameRoom.getPlayers().entrySet();
for (Map.Entry<String, WebSocketSession> player : players) {
if(!player.getValue().isOpen()){
String userId = player.getKey();
tagGameRoom.deleteUser(userId);
tagGameUserService.closedUser(userId).subscribe();
}
}
}
}


}
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ public void sendMessageToClients() {
.forEach(tagGameRoom -> {

// 1. 플레이어 정보를 조회하고 리스트로 변환
Flux<TagGameUser> usersFlux = Flux.fromIterable(tagGameRoom.getPlayers())
Flux<TagGameUser> usersFlux = Flux.fromIterable(tagGameRoom.getPlayers().entrySet())
.flatMap(player -> tagGameUserRepository.get(player.getKey()));

// 2. 유저 정보를 JSON으로 변환
Expand All @@ -46,8 +46,10 @@ public void sendMessageToClients() {
* 플레이어들에게 WebSocket 메시지 전송
*/
private Flux<Void> sendMessagesToPlayers(TagGameRoom tagGameRoom, String json) {
return Flux.fromIterable(tagGameRoom.getPlayers())
return Flux.fromIterable(tagGameRoom.getPlayers().entrySet())
.flatMap(player -> {
if(!player.getValue().isOpen())
return Mono.never();
WebSocketMessage webSocketMessage = player.getValue().textMessage(json);
return player.getValue().send(Mono.just(webSocketMessage));
});
Expand Down
Loading