@Slf4j
@Component
public class SignalHandler extends TextWebSocketHandler {
@Autowired
private GameRoomService gameRoomService;
@Autowired
private RepositoryService repositoryService;
private final SessionRepository sessionRepository = SessionRepository.getInstance();
private final ObjectMapper objectMapper = new ObjectMapper();
private static final String MSG_TYPE_JOIN_ROOM = "join_room";
private static final String MSG_TYPE_OFFER = "offer";
private static final String MSG_TYPE_ANSWER = "answer";
private static final String MSG_TYPE_CANDIDATE = "candidate";
@Override
public void afterConnectionEstablished(final WebSocketSession session) {
}
@Override
protected void handleTextMessage(final WebSocketSession session, final TextMessage textMessage) {
try {
WebSocketMessage message = objectMapper.readValue(textMessage.getPayload(), WebSocketMessage.class);
String userName = message.getSender();
Long roomId = message.getRoomId();
switch (message.getType()) {
case MSG_TYPE_JOIN_ROOM:
if (sessionRepository.hasRoom(roomId)) {
sessionRepository.addClient(roomId, session);
} else {
sessionRepository.addClientInNewRoom(roomId, session);
}
sessionRepository.saveRoomIdToSession(session, roomId);
sessionRepository.addNicknameInRoom(session.getId(), message.getNickname());
Map<String, WebSocketSession> joinClientList = sessionRepository.getClientList(roomId);
List<String> exportSessionList = new ArrayList<>();
for (Map.Entry<String, WebSocketSession> entry : joinClientList.entrySet()) {
if (entry.getValue() != session) {
exportSessionList.add(entry.getKey());
}
}
Map<String, String> exportNicknameList = new HashMap<>();
for (Map.Entry<String, WebSocketSession> entry : joinClientList.entrySet()) {
if (entry.getValue() != session) {
exportNicknameList.put(entry.getKey(), sessionRepository.getNicknameInRoom(entry.getKey()));
}
}
sendMessage(session,
new WebSocketResponseMessage().builder()
.type("all_users")
.sender(userName)
.data(message.getData())
.allUsers(exportSessionList)
.allUsersNickNames(exportNicknameList)
.candidate(message.getCandidate())
.sdp(message.getSdp())
.build());
break;
case MSG_TYPE_OFFER:
case MSG_TYPE_ANSWER:
case MSG_TYPE_CANDIDATE:
if (sessionRepository.hasRoom(roomId)) {
Map<String, WebSocketSession> oacClientList = sessionRepository.getClientList(roomId);
if (oacClientList.containsKey(message.getReceiver())) {
WebSocketSession ws = oacClientList.get(message.getReceiver());
sendMessage(ws,
new WebSocketResponseMessage().builder()
.type(message.getType())
.sender(session.getId())
.senderNickName(message.getNickname())
.receiver(message.getReceiver())
.data(message.getData())
.offer(message.getOffer())
.answer(message.getAnswer())
.candidate(message.getCandidate())
.sdp(message.getSdp())
.build());
}
} else {
throw new CustomException(CHAT_ROOM_NOT_FOUND);
}
break;
default:
log.info("======================================== DEFAULT");
log.info("============== 들어온 타입 : " + message.getType());
}
} catch (JsonProcessingException e) {
log.info("=================== SignalHandler Json처리 에러 : {} ", e.getMessage());
}
}
@Override
public void afterConnectionClosed(final WebSocketSession session, final CloseStatus status) {
String nickname = sessionRepository.getNicknameInRoom(session.getId());
Long roomId = sessionRepository.getRoomId(session);
sessionRepository.deleteClient(roomId, session);
sessionRepository.deleteRoomIdToSession(session);
sessionRepository.deleteNicknameInRoom(session.getId());
for(Map.Entry<String, WebSocketSession> oneClient : sessionRepository.getClientList(roomId).entrySet()){
sendMessage(oneClient.getValue(),
new WebSocketResponseMessage().builder()
.type("leave")
.sender(session.getId())
.receiver(oneClient.getKey())
.build());
}
Member member = repositoryService.findMemberByNickname(nickname);
List<GameRoomAttendee> gameRoomAttendeeList = repositoryService.findAttendeeByRoomId(roomId);
for(GameRoomAttendee gameRoomAttendee : gameRoomAttendeeList) {
if(nickname.equals(gameRoomAttendee.getMemberNickname())){
gameRoomService.roomExit(roomId, member);
}
}
}
private synchronized void sendMessage(WebSocketSession session, WebSocketResponseMessage message) {
try {
String json = objectMapper.writeValueAsString(message);
session.sendMessage(new TextMessage(json));
} catch (IOException e) {
log.info("============== 발생한 에러 메세지: {}", e.getMessage());
}
}
}