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

Feat #54 이미지 추가해서 반환 #54

Merged
merged 6 commits into from
Feb 1, 2025
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
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import com.gachtaxi.domain.chat.dto.request.ChatMessageRequest;
import com.gachtaxi.domain.chat.dto.response.ChatResponse;
import com.gachtaxi.domain.chat.dto.response.ChattingRoomCountResponse;
import com.gachtaxi.domain.chat.dto.response.ChattingRoomResponse;
import com.gachtaxi.domain.chat.service.ChattingRoomService;
import com.gachtaxi.domain.chat.service.ChattingService;
Expand Down Expand Up @@ -48,6 +49,15 @@ public ApiResponse<ChatResponse> getChattingMessages(@PathVariable Long roomId,
return ApiResponse.response(OK, GET_CHATTING_MESSAGE_SUCCESS.getMessage(), response);
}

@GetMapping("/api/chat/count/{roomId}")
@Operation(summary = "채팅방의 총 참여자 수를 조회하기 위한 API입니다.")
public ApiResponse<ChattingRoomCountResponse> getChattingMessageCount(@CurrentMemberId Long memberId,
@PathVariable Long roomId) {
ChattingRoomCountResponse response = chattingRoomService.getCount(memberId, roomId);

return ApiResponse.response(OK, GET_CHATTING_PARTICIPANT_COUNT_SUCCESS.getMessage(), response);
}

@DeleteMapping("/api/chat/{roomId}")
@Operation(summary = "채팅방을 퇴장하는 API입니다. 퇴장시 STOMP UNSUBSCRIBE를 꼭 해주세요")
public ApiResponse<Void> exitChattingRoom(@PathVariable Long roomId,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@ public enum ResponseMessage {

CREATE_CHATTING_ROOM_SUCCESS("채팅방 생성에 성공했습니다."),
GET_CHATTING_MESSAGE_SUCCESS("이전 메시지 조회에 성공 했습니다."),
EXIT_CHATTING_ROOM_SUCCESS("채팅방 퇴장에 성공했습니다.");
EXIT_CHATTING_ROOM_SUCCESS("채팅방 퇴장에 성공했습니다."),
GET_CHATTING_PARTICIPANT_COUNT_SUCCESS("채팅방 전체 참여자 조회에 성공했습니다.");

private final String message;
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ public record ChatMessage(
Long senderId,
String senderName,
String message,
String profilePicture,
ReadMessageRange range,
Long unreadCount,
LocalDateTime timeStamp,
Expand All @@ -28,6 +29,7 @@ public static ChatMessage from(ChattingMessage chattingMessage) {
.senderId(chattingMessage.getSenderId())
.senderName(chattingMessage.getSenderName())
.message(chattingMessage.getMessage())
.profilePicture(chattingMessage.getProfilePicture())
.unreadCount(chattingMessage.getUnreadCount())
.timeStamp(chattingMessage.getTimeStamp())
.messageType(chattingMessage.getMessageType())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ public record ChatResponse(
public static ChatResponse of(ChattingParticipant chattingParticipant, List<ChattingMessageResponse> chattingMessages, ChatPageableResponse chatPageableResponse) {
return ChatResponse.builder()
.memberId(chattingParticipant.getMembers().getId())
.disconnectedAt(chattingParticipant.getLastReadAt())
.disconnectedAt(chattingParticipant.getDisconnectedAt())
.chattingMessage(chattingMessages)
.pageable(chatPageableResponse)
.build();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ public record ChattingMessageResponse(
Long senderId,
String senderName,
String message,
String profilePicture,
Long unreadCount,
LocalDateTime timeStamp,
MessageType messageType
Expand All @@ -22,6 +23,7 @@ public static ChattingMessageResponse from(ChattingMessage chattingMessage) {
.senderId(chattingMessage.getSenderId())
.senderName(chattingMessage.getSenderName())
.message(chattingMessage.getMessage())
.profilePicture(chattingMessage.getProfilePicture())
.unreadCount(chattingMessage.getUnreadCount())
.timeStamp(chattingMessage.getTimeStamp())
.messageType(chattingMessage.getMessageType())
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package com.gachtaxi.domain.chat.dto.response;

public record ChattingRoomCountResponse(
Long roomId,
Long totalParticipantCount
) {
public static ChattingRoomCountResponse of(Long roomId, Long totalParticipantCount) {
return new ChattingRoomCountResponse(roomId, totalParticipantCount);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ public class ChattingMessage {

private String senderName;

private String profilePicture;

private Long roomId;

private String message;
Expand All @@ -38,12 +40,13 @@ public class ChattingMessage {
@LastModifiedDate
private LocalDateTime updatedAt;

public static ChattingMessage of(ChatMessageRequest request, long roomId, long senderId, String senderName, long unreadCount) {
public static ChattingMessage of(ChatMessageRequest request, long roomId, long senderId, String senderName, long unreadCount, String profilePicture) {
return ChattingMessage.builder()
.senderId(senderId)
.senderName(senderName)
.roomId(roomId)
.message(request.message())
.profilePicture(profilePicture)
.unreadCount(unreadCount)
.messageType(MessageType.MESSAGE)
.timeStamp(LocalDateTime.now())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ public class ChattingParticipant extends BaseEntity {
@CreatedDate
private LocalDateTime lastReadAt;

private LocalDateTime disconnectedAt;

public static ChattingParticipant of(ChattingRoom chattingRoom, Members members) {
return ChattingParticipant.builder()
.chattingRoom(chattingRoom)
Expand All @@ -48,9 +50,11 @@ public void reSubscribe() {

public void unsubscribe() {
this.lastReadAt = LocalDateTime.now();
this.disconnectedAt = LocalDateTime.now();
}

public void disconnect() {
this.lastReadAt = LocalDateTime.now();
this.disconnectedAt = LocalDateTime.now();
}
}
Original file line number Diff line number Diff line change
@@ -1,34 +1,35 @@
package com.gachtaxi.domain.chat.service;

import com.gachtaxi.domain.chat.exception.ChattingRoomNotFoundException;
import com.gachtaxi.domain.chat.exception.UnSubscriptionException;
import lombok.RequiredArgsConstructor;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.util.Optional;

@Service
@RequiredArgsConstructor
public class ChattingRedisService {
public static final String REDIS_CHAT_KEY_PREFIX = "ROOM:";

private final RedisTemplate<String, Object> chatRoomRedisTemplate;

public void saveSubscribeMember(long roomId, long senderId) {
public void saveSubscribeMember(long roomId, long senderId, String profilePicture) {
String key = getKey(roomId);

chatRoomRedisTemplate.opsForSet().add(key, senderId);
chatRoomRedisTemplate.opsForHash().put(key, String.valueOf(senderId), profilePicture);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

사진도 함께 저장하는군요!!
좋은 방식인 것 같습니다!!

Copy link
Member

@huncozyboy huncozyboy Jan 30, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

기존 opsForSet을 활용하여 사용자 정보를 저장하던 방식을 opsForHash를 사용해서 사용자의 프로필 사진을 함께 저장하는 로직으로 변경된걸 확인했습니다 !
동시에 opsForHash를 사용할 경우에 관련 데이터가 삭제될때((매칭 종료 이후나 사용자에 의해 채팅방 퇴장), 올바르게 삭제 로직이 이루어지는지 테스트가 필요해보입니다

Copy link
Member Author

@hyxklee hyxklee Jan 31, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

이벤트 리스너를 구현을 해서, 웹소켓 구독 해제시 데이터가 제거 되도록 구현했고, 테스트도 완료했습니다!

}

public boolean isActive(long roomId, long senderId) {
String key = getKey(roomId);

return Boolean.TRUE.equals(chatRoomRedisTemplate.opsForSet().isMember(key, senderId));
return Boolean.TRUE.equals(chatRoomRedisTemplate.opsForHash().hasKey(key, String.valueOf(senderId)));
}

public void removeSubscribeMember(long roomId, long senderId) {
String key = getKey(roomId);

chatRoomRedisTemplate.opsForSet().remove(key, senderId);
chatRoomRedisTemplate.opsForHash().delete(key, String.valueOf(senderId));
}

public void checkSubscriptionStatus(long roomId, long senderId) {
Expand All @@ -40,13 +41,15 @@ public void checkSubscriptionStatus(long roomId, long senderId) {
public long getSubscriberCount(long roomId) {
String key = getKey(roomId);

Long size = chatRoomRedisTemplate.opsForSet().size(key);
return chatRoomRedisTemplate.opsForHash().size(key);
}

if (size == null) {
throw new ChattingRoomNotFoundException();
}
public String getProfilePicture(long roomId, long senderId) {
String key = getKey(roomId);

return size;
return Optional.ofNullable(chatRoomRedisTemplate.opsForHash().get(key, String.valueOf(senderId)))
.map(Object::toString)
.orElse(null);
}

private String getKey(long roomId) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.gachtaxi.domain.chat.service;

import com.gachtaxi.domain.chat.dto.request.ChatMessage;
import com.gachtaxi.domain.chat.dto.response.ChattingRoomCountResponse;
import com.gachtaxi.domain.chat.dto.response.ChattingRoomResponse;
import com.gachtaxi.domain.chat.entity.ChattingMessage;
import com.gachtaxi.domain.chat.entity.ChattingParticipant;
Expand Down Expand Up @@ -56,6 +57,13 @@ public void delete(long chattingRoomId) {
chattingRoom.delete();
}

public ChattingRoomCountResponse getCount(Long memberId, Long roomId) {
chattingParticipantService.find(roomId, memberId);
Long count = chattingParticipantService.getParticipantCount(roomId);

return ChattingRoomCountResponse.of(roomId, count);
}

@Transactional
public void subscribeChatRoom(long roomId, SimpMessageHeaderAccessor accessor) {
Long senderId = (Long) accessor.getSessionAttributes().get(CHAT_USER_ID);
Expand All @@ -67,12 +75,12 @@ public void subscribeChatRoom(long roomId, SimpMessageHeaderAccessor accessor) {
accessor.getSessionAttributes().put(CHAT_USER_NAME, members.getNickname());

if (chattingParticipantService.checkSubscription(chattingRoom, members)) {
chattingRedisService.saveSubscribeMember(chattingRoom.getId(), members.getId());
chattingRedisService.saveSubscribeMember(chattingRoom.getId(), members.getId(), members.getProfilePicture());

return;
}

chattingRedisService.saveSubscribeMember(chattingRoom.getId(), members.getId());
chattingRedisService.saveSubscribeMember(chattingRoom.getId(), members.getId(), members.getProfilePicture());

ChattingParticipant newParticipant = ChattingParticipant.of(chattingRoom, members);
chattingParticipantService.save(newParticipant);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,8 +53,9 @@ public void chat(ChatMessageRequest request, SimpMessageHeaderAccessor accessor)
String senderName = getSessionAttribute(accessor, CHAT_USER_NAME, String.class);

long unreadCount = getUnreadCount(roomId);
String profilePicture = chattingRedisService.getProfilePicture(roomId, userId);

ChattingMessage chattingMessage = ChattingMessage.of(request, roomId, userId, senderName, unreadCount);
ChattingMessage chattingMessage = ChattingMessage.of(request, roomId, userId, senderName, unreadCount, profilePicture);

chattingMessageRepository.save(chattingMessage);

Expand Down Expand Up @@ -99,7 +100,7 @@ private Slice<ChattingMessage> loadMessage(long roomId, ChattingParticipant chat
}

private Slice<ChattingMessage> loadInitialMessage(long roomId, ChattingParticipant chattingParticipant, int pageSize) {
int chattingCount = chattingMessageRepository.countAllByRoomIdAndTimeStampAfterOrderByTimeStampDesc(roomId, chattingParticipant.getLastReadAt());
int chattingCount = chattingMessageRepository.countAllByRoomIdAndTimeStampAfterOrderByTimeStampDesc(roomId, chattingParticipant.getDisconnectedAt());

int effectivePageSize = Math.max(chattingCount, pageSize);
Pageable pageable = PageRequest.of(0, effectivePageSize, Sort.by(Sort.Direction.DESC, "timeStamp"));
Expand Down