Skip to content
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
@@ -1,16 +1,14 @@
package cmf.commitField.domain.chat.chatMessage.dto;

import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import lombok.*;

import java.time.LocalDateTime;

@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class ChatMsgDto {
private Long chatMsgId;
private Long userId;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
import cmf.commitField.domain.chat.chatMessage.repository.ChatMessageRepository;
import cmf.commitField.domain.chat.chatRoom.entity.ChatRoom;
import cmf.commitField.domain.chat.chatRoom.repository.ChatRoomRepository;
import cmf.commitField.domain.chat.userChatRoom.entity.UserChatRoom;
import cmf.commitField.domain.chat.userChatRoom.repository.UserChatRoomRepository;
import cmf.commitField.domain.user.entity.User;
import cmf.commitField.domain.user.repository.UserRepository;
import cmf.commitField.global.error.ErrorCode;
Expand All @@ -17,8 +19,9 @@
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
import java.util.Optional;

@Service
@RequiredArgsConstructor
Expand All @@ -28,6 +31,7 @@ public class ChatMessageServiceImpl implements ChatMessageService {
private final UserRepository userRepository;
private final ChatRoomRepository chatRoomRepository;
private final ChatMessageCustomRepository chatMessageCustomRepository;
private final UserChatRoomRepository userChatRoomRepository;

@Override
public ChatMsgResponse sendMessage(ChatMsgRequest message, Long userId, Long roomId) {
Expand Down Expand Up @@ -61,13 +65,24 @@ public List<ChatMsgDto> getRoomChatMsgList(Long roomId, Long userId, Long lastId
.orElseThrow(() -> new CustomException(ErrorCode.NOT_FOUND_USER));

List<ChatMsg> chatMsgsList = chatMessageCustomRepository.findChatRoomIdByChatMsg(roomId, lastId);
return chatMsgsList.stream().map(chatMsg -> new ChatMsgDto(
chatMsg.getId(),
chatMsg.getUser().getId(),
chatMsg.getUser().getNickname(),
chatMsg.getMessage(),
chatMsg.getCreatedAt()
))
.collect(Collectors.toList());
Optional<UserChatRoom> joinUser = userChatRoomRepository.findByUserIdAndChatRoomId(userId,roomId);
if (joinUser.isEmpty()) {
throw new CustomException(ErrorCode.NOT_FOUND_USER);
}
LocalDateTime joinDt = joinUser.get().getJoinDt();
List<ChatMsgDto> chatMsgDtos = new ArrayList<>();
for (ChatMsg chatMsg : chatMsgsList) {
ChatMsgDto build = ChatMsgDto.builder()
.chatMsgId(chatMsg.getId())
.nickname(chatMsg.getUser().getNickname())
.sendAt(chatMsg.getCreatedAt())
.message(chatMsg.getMessage())
.userId(chatMsg.getUser().getId())
.build();
if (build.getSendAt().isAfter(joinDt)) {
chatMsgDtos.add(build);
}
}
return chatMsgDtos;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -44,13 +44,13 @@ public GlobalResponse<Object> createRoom(

//채팅방 입장
@PostMapping("/room/join/{roomId}")
public GlobalResponse<Object> joinRoom(@PathVariable Long roomId) {
public GlobalResponse<Object> joinRoom(@PathVariable Long roomId, @RequestBody ChatRoomRequest chatRoomRequest) {
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();

if (authentication instanceof OAuth2AuthenticationToken) {
CustomOAuth2User principal = (CustomOAuth2User) authentication.getPrincipal();
Long userId = principal.getId(); // getId()를 통해 userId를 추출
chatRoomService.joinRoom(roomId, userId); // userId를 전달
chatRoomService.joinRoom(roomId, userId, chatRoomRequest); // userId를 전달
return GlobalResponse.success("해당 채팅방에 입장하셨습니다");
} else {
throw new IllegalArgumentException("로그인 후에 이용해 주세요.");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,5 +21,7 @@ public class ChatRoomRequest {
@Max(100)
private Integer userCountMax;

@Length(min = 4, max = 20)
private String password;

}
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,10 @@ public class ChatRoom extends BaseEntity {
@OneToMany(mappedBy = "chatRoom", fetch = FetchType.LAZY)
private List<Heart> hearts;

private String password;

private Boolean isPrivate;

@Override
public String toString() {
return "ChatRoom{" +
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,4 +34,5 @@ public interface ChatRoomService {

List<ChatRoomDto> myHeartRoomList(Long userId, Pageable pageable);

void joinRoom(Long roomId, Long userId, ChatRoomRequest chatRoomRequest);
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,14 @@
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

import static java.time.LocalDateTime.now;

@Service
@RequiredArgsConstructor
public class ChatRoomServiceImpl implements ChatRoomService {
Expand All @@ -52,6 +53,7 @@ public void createRoom(ChatRoomRequest chatRoomRequest, Long userId) {
// 유저정보 조회
User findUser = userRepository.findById(userId)
.orElseThrow(() -> new CustomException(ErrorCode.NOT_FOUND_USER));
String password = chatRoomRequest.getPassword();

// findUser가 null이 아닐 경우, User의 ID를 사용
if (findUser == null) {
Expand All @@ -63,19 +65,31 @@ public void createRoom(ChatRoomRequest chatRoomRequest, Long userId) {
.roomCreator(findUser.getId())
.title(chatRoomRequest.getTitle())
.userCountMax(chatRoomRequest.getUserCountMax())
.createdAt(LocalDateTime.now())
.modifiedAt(LocalDateTime.now())
.createdAt(now())
.modifiedAt(now())
.isPrivate(false)
.build();
if (password != null) {
chatRoom.setPassword(password);
chatRoom.setIsPrivate(true);
}
ChatRoom savedChatRoom = chatRoomRepository.save(chatRoom);

// 연관관계 user_chat room 생성
UserChatRoom userChatRoom = UserChatRoom.builder()
.user(findUser)
.chatRoom(savedChatRoom)
.joinDt(now())
.build();
userChatRoomRepository.save(userChatRoom);
}

@Override
public void joinRoom(Long roomId, Long userId) {

}


// 방 조회 DTO 변환 메서드 추출
private static List<ChatRoomDto> getChatRoomDtos(Page<ChatRoom> all) {
return all.stream()
Expand Down Expand Up @@ -111,7 +125,7 @@ public List<ChatRoomDto> getUserByRoomPartList(Long userId, Pageable pageable) {

@Override
@Transactional
public void joinRoom(Long roomId, Long userId) {
public void joinRoom(Long roomId, Long userId, ChatRoomRequest chatRoomRequest) {
RLock lock = redissonClient.getLock("joinRoomLock:" + roomId);
try {
boolean available = lock.tryLock(1, TimeUnit.SECONDS);
Expand All @@ -129,6 +143,15 @@ public void joinRoom(Long roomId, Long userId) {
// user_chatroom 현재 인원 카운트 (비즈니스 로직)
Long currentUserCount = userChatRoomRepository.countNonLockByChatRoomId(roomId); // lock (기존)

if (chatRoom.getIsPrivate() && chatRoomRequest.getPassword() == null) {
throw new CustomException(ErrorCode.NEED_TO_PASSWORD);



}
if (chatRoom.getIsPrivate() && !chatRoomRequest.getPassword().equals(chatRoom.getPassword())) {
throw new CustomException(ErrorCode.ROOM_PASSWORD_MISMATCH);
}
List<Long> userChatRoomByChatRoomId = userChatRoomRepository
.findUserChatRoomByChatRoom_Id(roomId);

Expand All @@ -144,6 +167,7 @@ public void joinRoom(Long roomId, Long userId) {
UserChatRoom userChatRoom = UserChatRoom.builder()
.user(findUser)
.chatRoom(chatRoom)
.joinDt(now())
.build();
userChatRoomRepository.save(userChatRoom);
// 비즈니스 로직 끝
Expand All @@ -160,6 +184,17 @@ public void joinRoom(Long roomId, Long userId) {
@Transactional
public void outRoom(Long userId, Long roomId) {
ChatRoom room = getChatRoom(roomId);
List<UserChatRoom> userByChatRoomId = userChatRoomRepository
.findUserByChatRoomId(roomId);
List<Long> userIds = new ArrayList<>();
for (UserChatRoom userChatRoom : userByChatRoomId) {
Long id = userChatRoom.getUser().getId();
userIds.add(id);
}
// 만약 방에 없는데 나가기를 시도한 경우
if (!userIds.contains(userId)) {
throw new CustomException(ErrorCode.METHOD_NOT_ALLOWED);
}
// 방장이 아니라면
if (!Objects.equals(room.getRoomCreator(), userId)) {
userChatRoomRepository.deleteUserChatRoomByChatRoom_IdAndUserId(roomId, userId);
Expand Down Expand Up @@ -197,7 +232,7 @@ public void updateRoom(Long roomId, ChatRoomUpdateRequest chatRoomUpdateRequest,
if (currentRoomTitle.equals(chatRoomUpdateRequest.getTitle())) {
throw new CustomException(ErrorCode.REQUEST_SAME_AS_CURRENT_TITLE);
}
room.update(chatRoomUpdateRequest.getTitle(), LocalDateTime.now());
room.update(chatRoomUpdateRequest.getTitle(), now());
chatRoomRepository.save(room);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@
import lombok.*;
import lombok.experimental.SuperBuilder;

import java.time.LocalDateTime;

@Entity
@Getter
@Setter
Expand All @@ -25,4 +27,7 @@ public class UserChatRoom extends BaseEntity {
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "chat_room_id",nullable = false)
private ChatRoom chatRoom;


private LocalDateTime joinDt;
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import org.springframework.stereotype.Repository;

import java.util.List;
import java.util.Optional;

@Repository
public interface UserChatRoomRepository extends JpaRepository<UserChatRoom, Long> {
Expand All @@ -32,6 +33,11 @@ public interface UserChatRoomRepository extends JpaRepository<UserChatRoom, Long
List<Long> findUserChatRoomByChatRoom_Id(Long chatRoomId);

List<UserChatRoom> findUserChatRoomByChatRoomId(Long roomId);
//out room 조회
List<UserChatRoom> findUserByChatRoomId(Long roomId);

Optional<UserChatRoom> findByUserId(Long userId);
//채팅방 join한 user
Optional<UserChatRoom> findByUserIdAndChatRoomId(Long userId, Long chatRoomId);

}
5 changes: 4 additions & 1 deletion src/main/java/cmf/commitField/global/error/ErrorCode.java
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,10 @@ public enum ErrorCode {

TOKEN_EXPIRED(HttpStatus.BAD_REQUEST, "토큰이 만료되었습니다."),

// member
// user_room
MEMBER_NOT_FOUND(HttpStatus.NOT_FOUND, "사용자를 찾을 수 없습니다"),
NEED_TO_PASSWORD(HttpStatus.BAD_REQUEST, "비밀번호를 입력해야 합니다."),
ROOM_PASSWORD_MISMATCH(HttpStatus.BAD_REQUEST, "방 비밀번호가 일치하지 않습니다."),

// season
NOT_FOUND_SEASON(HttpStatus.NOT_FOUND, "시즌을 찾을 수 없습니다."),
Expand All @@ -57,6 +59,7 @@ public enum ErrorCode {
NOT_EXIST_CLIENT(HttpStatus.NOT_FOUND, "채팅방에 사용자가 존재하지 않습니다."),
NOT_ROOM_MEMBER(HttpStatus.FORBIDDEN, "채팅방에 속한 유저가 아닙니다."),


//chatMessage
EMPTY_MESSAGE(HttpStatus.BAD_REQUEST, "채팅 메시지는 공백으로 보낼 수 없습니다."),
CHAT_NOT_FOUND(HttpStatus.NOT_FOUND, "해당 채팅방의 메시지들을 찾지 못했습니다."),
Expand Down
26 changes: 26 additions & 0 deletions src/main/java/cmf/commitField/global/kafka/Consumers.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package cmf.commitField.global.kafka;

import cmf.commitField.domain.chat.chatMessage.entity.ChatMsg;
import lombok.RequiredArgsConstructor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.messaging.handler.annotation.Payload;
import org.springframework.stereotype.Component;

import java.util.HashMap;
import java.util.Map;

@Component
@RequiredArgsConstructor
public class Consumers {
private final Logger logger = LoggerFactory.getLogger(Consumers.class);

public void consume(@Payload ChatMsg chatMsg) throws Exception {
logger.info("Consume msg : roomId : '{}', nickname :'{}', sender : '{}' ",
chatMsg.getId(), chatMsg.getUser().getNickname(), chatMsg.getMessage());
Map<String, String> msg = new HashMap<>();
msg.put("roomNum", String.valueOf(chatMsg.getChatRoom().getId()));
msg.put("message", chatMsg.getMessage());
msg.put("sender", chatMsg.getUser().getNickname());
}
}
20 changes: 20 additions & 0 deletions src/main/java/cmf/commitField/global/kafka/Producers.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package cmf.commitField.global.kafka;

import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

@Slf4j
@Component
@RequiredArgsConstructor
public class Producers {
private final Logger logger = LoggerFactory.getLogger(Producers.class);
// private final KafkaTemplate<String, String> kafkaTemplate;

public void produceMessage(String topic, String payload) {
logger.info("Topic : '{}' to Payload : '{}'", topic, payload);

}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,7 @@
import cmf.commitField.global.exception.CustomException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.web.socket.CloseStatus;
import org.springframework.web.socket.WebSocketHandler;
import org.springframework.web.socket.WebSocketMessage;
import org.springframework.web.socket.WebSocketSession;
import org.springframework.web.socket.*;

import java.io.IOException;
import java.util.*;
Expand Down Expand Up @@ -104,4 +101,13 @@ private Long extractRoomId(WebSocketSession session) {
}
return roomId;
}
//메세지 전송
public void sendMessage(String payload) throws Exception {
for (List<WebSocketSession> sessions : chatRooms.values()) {
for (WebSocketSession session : sessions) {
TextMessage msg = new TextMessage(payload);
session.sendMessage(msg);
}
}
}
}
Loading