Skip to content

Commit

Permalink
refactor: ping과 message 전송시 사용되는 data를 Dto로 변환하여 사용하도록 수정
Browse files Browse the repository at this point in the history
  • Loading branch information
swonny committed Apr 15, 2024
1 parent 193c332 commit 514e0ac
Show file tree
Hide file tree
Showing 11 changed files with 154 additions and 93 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
import org.springframework.web.socket.WebSocketSession;

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

import static com.ddang.ddang.chat.domain.WebSocketSessions.CHAT_ROOM_ID_KEY;
Expand All @@ -22,10 +21,8 @@ public void add(final WebSocketSession session, final Long chatRoomId) {
webSocketSessions.putIfAbsent(session, chatRoomId);
}

public Set<WebSocketSession> getSessionsByChatRoomId(final Long chatRoomId) {
final WebSocketSessions webSocketSessions = chatRoomSessions.get(chatRoomId);

return webSocketSessions.getSessions();
public WebSocketSessions findSessionsByChatRoomId(final Long chatRoomId) {
return chatRoomSessions.get(chatRoomId);
}

public boolean containsByUserId(final Long chatRoomId, final Long userId) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import org.springframework.web.socket.WebSocketSession;

import java.util.Collections;
import java.util.Optional;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;

Expand All @@ -27,6 +28,12 @@ public boolean contains(final Long userId) {
.anyMatch(session -> session.getAttributes().get(USER_ID_KEY) == userId);
}

public Optional<WebSocketSession> findByUserId(final long userId) {
return sessions.stream()
.filter(session -> session.getAttributes().get(USER_ID_KEY).equals(userId))
.findFirst();
}

public void remove(final WebSocketSession session) {
sessions.remove(session);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,18 @@

import com.ddang.ddang.websocket.handler.dto.ChatMessageType;
import com.ddang.ddang.websocket.handler.dto.SendMessageDto;
import com.ddang.ddang.websocket.handler.dto.SessionAttributeDto;
import com.fasterxml.jackson.core.JsonProcessingException;
import org.springframework.web.socket.WebSocketSession;

import java.util.List;
import java.util.Map;

public interface ChatHandleProvider {

List<SendMessageDto> createResponse(final WebSocketSession session, final Map<String, String> data) throws JsonProcessingException;
List<SendMessageDto> createResponse(
final SessionAttributeDto sessionAttributeDto,
final Map<String, String> data
) throws JsonProcessingException;

ChatMessageType supportsChatType();
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,10 @@
import com.ddang.ddang.websocket.handler.WebSocketHandleTextMessageProvider;
import com.ddang.ddang.websocket.handler.dto.ChatMessageType;
import com.ddang.ddang.websocket.handler.dto.SendMessageDto;
import com.ddang.ddang.websocket.handler.dto.SessionAttributeDto;
import com.ddang.ddang.websocket.handler.dto.TextMessageType;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Component;
import org.springframework.web.socket.WebSocketSession;
Expand All @@ -20,6 +22,7 @@ public class ChatWebSocketHandleTextMessageProvider implements WebSocketHandleTe
private static final String CHATROOM_ID_KEY = "chatRoomId";
private static final String TYPE_KEY = "type";

private final ObjectMapper objectMapper;
private final WebSocketChatSessions sessions;
private final ChatHandleTypeProviderComposite chatHandleTypeProviderComposite;

Expand All @@ -39,7 +42,13 @@ public List<SendMessageDto> handleCreateSendMessage(
final ChatMessageType type = ChatMessageType.findMessageType(chatMessageData.get(TYPE_KEY));
final ChatHandleProvider provider = chatHandleTypeProviderComposite.findProvider(type);

return provider.createResponse(session, chatMessageData);
return provider.createResponse(convertToSessionAttributeDto(session), chatMessageData);
}

private SessionAttributeDto convertToSessionAttributeDto(final WebSocketSession session) {
final Map<String, Object> attributes = session.getAttributes();

return objectMapper.convertValue(attributes, SessionAttributeDto.class);
}

private long getChatRoomId(final Map<String, String> data) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,11 @@
import com.ddang.ddang.chat.application.event.UpdateReadMessageLogEvent;
import com.ddang.ddang.chat.domain.Message;
import com.ddang.ddang.chat.domain.WebSocketChatSessions;
import com.ddang.ddang.chat.domain.WebSocketSessions;
import com.ddang.ddang.chat.handler.dto.ChatMessageDataDto;
import com.ddang.ddang.chat.handler.dto.SendChatResponse;
import com.ddang.ddang.chat.handler.dto.MessageDataDto;
import com.ddang.ddang.chat.handler.dto.MessageDto;
import com.ddang.ddang.chat.handler.dto.SendChatResponse;
import com.ddang.ddang.chat.handler.dto.SendMessageStatus;
import com.ddang.ddang.chat.presentation.dto.request.CreateMessageRequest;
import com.ddang.ddang.websocket.handler.dto.ChatMessageType;
Expand All @@ -25,7 +27,6 @@
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;

@Component
@RequiredArgsConstructor
Expand All @@ -44,32 +45,24 @@ public ChatMessageType supportsChatType() {

@Override
public List<SendMessageDto> createResponse(
final WebSocketSession session,
final SessionAttributeDto sessionAttributeDto,
final Map<String, String> data
) throws JsonProcessingException {
final SessionAttributeDto sessionAttributes = getSessionAttributes(session);

return createSendMessageResponse(data, sessionAttributes);
}
final Long writerId = sessionAttributeDto.userId();
final MessageDataDto messageDataDto = MessageDataDto.from(data);

final Message message = createMessage(data, writerId);

private SessionAttributeDto getSessionAttributes(final WebSocketSession session) {
final Map<String, Object> attributes = session.getAttributes();
sendNotificationIfReceiverNotInSession(message, sessionAttributeDto);

return objectMapper.convertValue(attributes, SessionAttributeDto.class);
return createSendMessages(message, writerId, messageDataDto.chatRoomId());
}

private List<SendMessageDto> createSendMessageResponse(
final Map<String, String> data,
final SessionAttributeDto sessionAttribute
) throws JsonProcessingException {
final Long writerId = sessionAttribute.userId();
private Message createMessage(final Map<String, String> data, final long writerId) {
final ChatMessageDataDto messageData = objectMapper.convertValue(data, ChatMessageDataDto.class);
final CreateMessageDto createMessageDto = createMessageDto(messageData, writerId);
final Message message = messageService.create(createMessageDto);
sendNotificationIfReceiverNotInSession(message, sessionAttribute);

return createSendMessages(message, writerId, createMessageDto.chatRoomId());
return messageService.create(createMessageDto);
}

private void sendNotificationIfReceiverNotInSession(
Expand All @@ -80,8 +73,8 @@ private void sendNotificationIfReceiverNotInSession(
final String profileImageAbsoluteUrl = String.valueOf(sessionAttribute.baseUrl());
messageNotificationEventPublisher.publishEvent(new MessageNotificationEvent(
message,
profileImageAbsoluteUrl)
);
profileImageAbsoluteUrl
));
}
}

Expand All @@ -90,10 +83,10 @@ private List<SendMessageDto> createSendMessages(
final Long writerId,
final Long chatRoomId
) throws JsonProcessingException {
final Set<WebSocketSession> groupSessions = sessions.getSessionsByChatRoomId(message.getChatRoom().getId());
final WebSocketSessions groupSessions = sessions.findSessionsByChatRoomId(message.getChatRoom().getId());

final List<SendMessageDto> sendMessageDtos = new ArrayList<>();
for (final WebSocketSession currentSession : groupSessions) {
for (final WebSocketSession currentSession : groupSessions.getSessions()) {
final MessageDto messageDto = MessageDto.of(message, isMyMessage(currentSession, writerId));
final TextMessage textMessage = createTextMessage(messageDto);
sendMessageDtos.add(new SendMessageDto(currentSession, textMessage));
Expand All @@ -103,10 +96,27 @@ private List<SendMessageDto> createSendMessages(
return sendMessageDtos;
}

private CreateMessageDto createMessageDto(
final ChatMessageDataDto messageData,
final Long userId
private void updateReadMessageLog(
final WebSocketSession currentSession,
final Long chatRoomId,
final Message message
) {
final SessionAttributeDto sessionAttributes = convertToSessionAttributeDto(currentSession);
final UpdateReadMessageLogEvent updateReadMessageLogEvent = new UpdateReadMessageLogEvent(
sessionAttributes.userId(),
chatRoomId,
message.getId()
);
messageLogEventPublisher.publishEvent(updateReadMessageLogEvent);
}

private SessionAttributeDto convertToSessionAttributeDto(final WebSocketSession session) {
final Map<String, Object> attributes = session.getAttributes();

return objectMapper.convertValue(attributes, SessionAttributeDto.class);
}

private CreateMessageDto createMessageDto(final ChatMessageDataDto messageData, final Long userId) {
final CreateMessageRequest request = new CreateMessageRequest(messageData.receiverId(), messageData.contents());

return CreateMessageDto.of(userId, messageData.chatRoomId(), request);
Expand All @@ -122,25 +132,8 @@ private boolean isMyMessage(
}

private TextMessage createTextMessage(final MessageDto messageDto) throws JsonProcessingException {
final SendChatResponse sendChatResponse = new SendChatResponse(
SendMessageStatus.SUCCESS,
List.of(messageDto)
);
final SendChatResponse sendChatResponse = new SendChatResponse(SendMessageStatus.SUCCESS, List.of(messageDto));

return new TextMessage(objectMapper.writeValueAsString(sendChatResponse));
}

private void updateReadMessageLog(
final WebSocketSession currentSession,
final Long chatRoomId,
final Message message
) {
final SessionAttributeDto sessionAttributes = getSessionAttributes(currentSession);
final UpdateReadMessageLogEvent updateReadMessageLogEvent = new UpdateReadMessageLogEvent(
sessionAttributes.userId(),
chatRoomId,
message.getId()
);
messageLogEventPublisher.publishEvent(updateReadMessageLogEvent);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,12 @@

import com.ddang.ddang.chat.application.MessageService;
import com.ddang.ddang.chat.application.dto.ReadMessageDto;
import com.ddang.ddang.chat.domain.WebSocketChatSessions;
import com.ddang.ddang.chat.domain.WebSocketSessions;
import com.ddang.ddang.chat.handler.dto.ChatPingDto;
import com.ddang.ddang.chat.handler.dto.SendChatResponse;
import com.ddang.ddang.chat.handler.dto.MessageDto;
import com.ddang.ddang.chat.handler.dto.PingDataDto;
import com.ddang.ddang.chat.handler.dto.SendChatResponse;
import com.ddang.ddang.chat.handler.dto.SendMessageStatus;
import com.ddang.ddang.chat.presentation.dto.request.ReadMessageRequest;
import com.ddang.ddang.websocket.handler.dto.ChatMessageType;
Expand All @@ -19,11 +22,13 @@

import java.util.List;
import java.util.Map;
import java.util.NoSuchElementException;

@Component
@RequiredArgsConstructor
public class PingTypeHandler implements ChatHandleProvider {

private final WebSocketChatSessions sessions;
private final ObjectMapper objectMapper;
private final MessageService messageService;

Expand All @@ -34,35 +39,29 @@ public ChatMessageType supportsChatType() {

@Override
public List<SendMessageDto> createResponse(
final WebSocketSession session,
final SessionAttributeDto sessionAttributeDto,
final Map<String, String> chatPingData
) throws JsonProcessingException {
final ReadMessageRequest readMessageRequest = createReadMessageRequest(session, chatPingData);
final PingDataDto pingDataDto = PingDataDto.from(chatPingData);
final ReadMessageRequest readMessageRequest = createReadMessageRequest(sessionAttributeDto, pingDataDto);
final List<ReadMessageDto> readMessageDtos = messageService.readAllByLastMessageId(readMessageRequest);
final SendChatResponse sendChatResponse = createSendChatResponse(readMessageDtos, session);
final SendChatResponse sendChatResponse = createSendChatResponse(readMessageDtos, sessionAttributeDto);

return List.of(createSendMessageDto(session, sendChatResponse));
return List.of(createSendMessageDto(sessionAttributeDto, pingDataDto, sendChatResponse));
}

private ReadMessageRequest createReadMessageRequest(
final WebSocketSession session,
final Map<String, String> chatPingData
final SessionAttributeDto sessionAttributeDto,
final PingDataDto chatPingData
) {
final SessionAttributeDto sessionAttribute = convertToSessionAttributes(session);
final ChatPingDto pingDto = objectMapper.convertValue(chatPingData, ChatPingDto.class);

return new ReadMessageRequest(sessionAttribute.userId(), pingDto.chatRoomId(), pingDto.lastMessageId());
}

private SessionAttributeDto convertToSessionAttributes(final WebSocketSession session) {
final Map<String, Object> attributes = session.getAttributes();

return objectMapper.convertValue(attributes, SessionAttributeDto.class);
return new ReadMessageRequest(sessionAttributeDto.userId(), pingDto.chatRoomId(), pingDto.lastMessageId());
}

private SendChatResponse createSendChatResponse(
final List<ReadMessageDto> readMessageDtos,
final WebSocketSession session
final SessionAttributeDto session
) {
final List<MessageDto> messageDtos = convertToMessageDto(readMessageDtos, session);

Expand All @@ -71,29 +70,32 @@ private SendChatResponse createSendChatResponse(

private List<MessageDto> convertToMessageDto(
final List<ReadMessageDto> readMessageDtos,
final WebSocketSession session
final SessionAttributeDto sessionAttributeDto
) {
return readMessageDtos.stream()
.map(readMessageDto -> MessageDto.of(readMessageDto,
isMyMessage(session, readMessageDto.writerId())
))
.toList();
.map(readMessageDto -> MessageDto.of(readMessageDto, isMyMessage(sessionAttributeDto,
readMessageDto.writerId()
))).toList();
}

private boolean isMyMessage(
final WebSocketSession session, final Long writerId
) {
final long userId = Long.parseLong(String.valueOf(session.getAttributes().get("userId")));
private boolean isMyMessage(final SessionAttributeDto session, final Long writerId) {
final long userId = session.userId();

return writerId.equals(userId);
}

private SendMessageDto createSendMessageDto(
final WebSocketSession session,
final SessionAttributeDto sessionAttributeDto,
final PingDataDto chatPingData,
final SendChatResponse sendChatResponse
) throws JsonProcessingException {
final TextMessage textMessage = new TextMessage(objectMapper.writeValueAsString(sendChatResponse));
final WebSocketSessions sessions = this.sessions.findSessionsByChatRoomId(chatPingData.chatRoomId());
final WebSocketSession userSession = sessions.findByUserId(sessionAttributeDto.userId())
.orElseThrow(() -> new NoSuchElementException(
"웹소켓에 연결된 사용자가 존재하지 않습니다."
));

return new SendMessageDto(session, textMessage);
return new SendMessageDto(userSession, textMessage);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package com.ddang.ddang.chat.handler.dto;

import java.util.Map;

public record MessageDataDto(long chatRoomId, long receiverId, String contents) {

private static final String CHAT_ROOM_ID_KEY = "chatRoomId";
private static final String RECEIVER_ID_KEY = "receiverId";
private static final String CONTENTS_ID_KEY = "contents";

public static MessageDataDto from(final Map<String, String> data) {
return new MessageDataDto(
Long.parseLong(data.get(CHAT_ROOM_ID_KEY)),
Long.parseLong(data.get(RECEIVER_ID_KEY)),
data.get(CONTENTS_ID_KEY)
);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package com.ddang.ddang.chat.handler.dto;

import java.util.Map;

public record PingDataDto(long chatRoomId, long lastMessageId) {

private static final String CHAT_ROOM_ID_KEY = "chatRoomId";
private static final String LAST_MESSAGE_ID = "lastMessageId";

public static PingDataDto from(final Map<String, String> chatPingData) {
return new PingDataDto(Long.parseLong(chatPingData.get(CHAT_ROOM_ID_KEY)),
Long.parseLong(chatPingData.get(LAST_MESSAGE_ID))
);
}
}
Loading

0 comments on commit 514e0ac

Please sign in to comment.