diff --git a/src/main/java/shop/geeksasangchat/common/websocket/SocketHandler.java b/src/main/java/shop/geeksasangchat/common/websocket/SocketHandler.java index 938d7b9..4f253d1 100644 --- a/src/main/java/shop/geeksasangchat/common/websocket/SocketHandler.java +++ b/src/main/java/shop/geeksasangchat/common/websocket/SocketHandler.java @@ -1,6 +1,8 @@ package shop.geeksasangchat.common.websocket; +import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; import lombok.RequiredArgsConstructor; import org.springframework.amqp.rabbit.core.RabbitTemplate; import org.springframework.stereotype.Component; @@ -8,6 +10,7 @@ import org.springframework.web.socket.TextMessage; import org.springframework.web.socket.WebSocketSession; import org.springframework.web.socket.handler.TextWebSocketHandler; +import shop.geeksasangchat.dto.PostChattingRes; import shop.geeksasangchat.rabbitmq.ChattingVO; import java.util.HashMap; @@ -30,12 +33,29 @@ public void handleTextMessage(WebSocketSession session, TextMessage message) { System.out.println("전송하는 웹소켓 메시지="+msg); try { - ObjectMapper mapper = new ObjectMapper(); +// ObjectMapper mapper = new ObjectMapper(); + ObjectMapper mapper = new ObjectMapper().registerModule(new JavaTimeModule()); ChattingVO chattingVO = mapper.readValue(msg, ChattingVO.class); String exchangeName = "chatting-" + "exchange-" + chattingVO.getChattingRoomUUID(); - rabbitTemplate.convertAndSend(exchangeName, "asd", chattingVO.getMsg()); + // json 형식으로 변환 후 전송 +// ObjectMapper mapper = new ObjectMapper().registerModule(new JavaTimeModule()); +// PostChattingRes postChattingRes = new PostChattingRes(chattingRoomId, saveChatting.getContent(), saveChatting.getBaseEntity().getCreatedAt()); // ObjectMapper가 java8의 LocalDateTime을 지원하지 않는 에러 해결 +// PostChattingRes postChattingRes = mapper.readValue(msg, PostChattingRes.class); + String saveChattingJsonStr = null; + try { + saveChattingJsonStr = mapper.writeValueAsString(chattingVO); + } catch (JsonProcessingException e) { + e.printStackTrace(); + } +// for(int i=0;i createPartyChattingRoom(HttpServletRequest request){ +// JwtInfo jwtInfo = (JwtInfo) request.getAttribute("jwtInfo"); +// String id = partyChattingService.createChattingRoom(jwtInfo.getUserId(), "title"); +// return new BaseResponse(id); +// } + @NoIntercept //TODO:개발을 위해 임시로 jwt 허용되게한 것. 추후 제거 바람. public BaseResponse createPartyChattingRoom(HttpServletRequest request){ - JwtInfo jwtInfo = (JwtInfo) request.getAttribute("jwtInfo"); - String id = partyChattingService.createChattingRoom(jwtInfo.getUserId(), "title"); +// JwtInfo jwtInfo = (JwtInfo) request.getAttribute("jwtInfo"); + String id = partyChattingService.createChattingRoom(1, "title"); return new BaseResponse(id); } @PostMapping("/chatting") +// @NoIntercept //TODO:개발을 위해 임시로 jwt 허용되게한 것. 추후 제거 바람. +// public BaseResponse createPartyChatting(HttpServletRequest request, @RequestBody PostChattingReq dto){ +// JwtInfo jwtInfo = (JwtInfo) request.getAttribute("jwtInfo"); +// System.out.println("dto.getChattingRoomId() = " + dto.getChattingRoomId()); +// partyChattingService.createChatting(jwtInfo.getUserId(), dto.getChattingRoomId(), dto.getContent(), dto.getParticipantsCnt()); +// return new BaseResponse("채팅송신을 성공했습니다."); +// } + @NoIntercept //TODO:개발을 위해 임시로 jwt 허용되게한 것. 추후 제거 바람. public BaseResponse createPartyChatting(HttpServletRequest request, @RequestBody PostChattingReq dto){ - JwtInfo jwtInfo = (JwtInfo) request.getAttribute("jwtInfo"); +// JwtInfo jwtInfo = (JwtInfo) request.getAttribute("jwtInfo"); System.out.println("dto.getChattingRoomId() = " + dto.getChattingRoomId()); - partyChattingService.createChatting(jwtInfo.getUserId(), dto.getChattingRoomId(), dto.getContent(), dto.getParticipantsCnt()); + partyChattingService.createChatting(1, dto.getChattingRoomId(), dto.getContent(), dto.getParticipantsCnt()); return new BaseResponse("채팅송신을 성공했습니다."); } + @PostMapping("/member") + @NoIntercept //TODO:개발을 위해 임시로 jwt 허용되게한 것. 추후 제거 바람. + public BaseResponse joinPartyChattingRoom(HttpServletRequest request, @RequestBody PostParticipantInfoReq postPartyChattingRoomMember){ + partyChattingService.joinPartyChattingRoom(postPartyChattingRoomMember.getChattingRoomId(), LocalDateTime.now(), postPartyChattingRoomMember.getIsRemittance(), postPartyChattingRoomMember.getNickName()); + return new BaseResponse("채팅방에 멤버가 추가되었습니다."); + } + @ApiOperation(value = "채팅방 전체 조회", notes = "(jwt 토큰 필요)전체 조회") @ApiResponses({ diff --git a/src/main/java/shop/geeksasangchat/domain/Chatting.java b/src/main/java/shop/geeksasangchat/domain/Chatting.java index 1175f33..6383f4d 100644 --- a/src/main/java/shop/geeksasangchat/domain/Chatting.java +++ b/src/main/java/shop/geeksasangchat/domain/Chatting.java @@ -9,6 +9,8 @@ import shop.geeksasangchat.common.domain.BaseEntity; import java.io.Serializable; +import java.util.ArrayList; +import java.util.List; //Serializable : 자바에서 직렬화를 통해 object를 빠르게 보낼 수 있음/ 외부로 데이터 보내는데 필요? @Document //@Document는객체를 몽고DB에 영속화시킴 = SpringDataJpa의 @Entity와 같은 역할 @@ -20,9 +22,17 @@ public class Chatting implements Serializable { public String id; public String content; -// -// @DocumentReference(lazy = true) -// private PartyChattingRoom partyChattingRoom; + + @DocumentReference(lazy = true) // 다대일 + private PartyChattingRoom partyChattingRoom; + + private Boolean isSystemMessage; + + private String senderNickName; + + private String senderImgUrl; + + private List readMembers = new ArrayList<>(); // 읽은 멤버 리스트 @Unwrapped(onEmpty = Unwrapped.OnEmpty.USE_EMPTY) private BaseEntity baseEntity; @@ -31,12 +41,16 @@ public Chatting(String content) { this.content = content; this.baseEntity = new BaseEntity(); } -// -// public Chatting(String content, PartyChattingRoom partyChattingRoom) { -// this.content = content; -// this.partyChattingRoom = partyChattingRoom; -// this.baseEntity = new BaseEntity(); -// } + + public Chatting(String content, PartyChattingRoom partyChattingRoom, Boolean isSystemMessage, String senderNickName, String senderImgUrl, List readMembers) { + this.content = content; + this.partyChattingRoom = partyChattingRoom; + this.isSystemMessage = isSystemMessage; + this.senderNickName = senderNickName; + this.senderImgUrl = senderImgUrl; + this.readMembers = readMembers; + this.baseEntity = new BaseEntity(); + } } /** diff --git a/src/main/java/shop/geeksasangchat/domain/ChattingRoom.java b/src/main/java/shop/geeksasangchat/domain/ChattingRoom.java index 9a19bf7..b58e456 100644 --- a/src/main/java/shop/geeksasangchat/domain/ChattingRoom.java +++ b/src/main/java/shop/geeksasangchat/domain/ChattingRoom.java @@ -6,7 +6,7 @@ import org.springframework.data.mongodb.core.mapping.Unwrapped; import shop.geeksasangchat.common.domain.BaseEntity; -@Document //추상 클래스로 때려 박을 수 있음. 신기 +//@Document //추상 클래스로 때려 박을 수 있음. 신기 public abstract class ChattingRoom { // 배달, 중고거래, 커뮤니티 등 서로다른 분류의 채팅방 공통 부분 추상 클래스 @Id diff --git a/src/main/java/shop/geeksasangchat/domain/ParticipantInfo.java b/src/main/java/shop/geeksasangchat/domain/ParticipantInfo.java new file mode 100644 index 0000000..ed5361c --- /dev/null +++ b/src/main/java/shop/geeksasangchat/domain/ParticipantInfo.java @@ -0,0 +1,25 @@ +package shop.geeksasangchat.domain; + +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.ToString; +import org.springframework.data.mongodb.core.mapping.Document; + +import java.time.LocalDate; +import java.time.LocalDateTime; + +@Document //@Document는객체를 몽고DB에 영속화시킴 = SpringDataJpa의 @Entity와 같은 역할 +@ToString +@Getter +@NoArgsConstructor +public class ParticipantInfo { + private LocalDateTime enterTime; + private boolean isRemittance; + private String nickName; + + public ParticipantInfo(LocalDateTime enterTime, boolean isRemittance, String nickName) { + this.enterTime = enterTime; + this.isRemittance = isRemittance; + this.nickName = nickName; + } +} diff --git a/src/main/java/shop/geeksasangchat/domain/PartyChattingRoom.java b/src/main/java/shop/geeksasangchat/domain/PartyChattingRoom.java index 7d79430..78f1600 100644 --- a/src/main/java/shop/geeksasangchat/domain/PartyChattingRoom.java +++ b/src/main/java/shop/geeksasangchat/domain/PartyChattingRoom.java @@ -1,11 +1,16 @@ package shop.geeksasangchat.domain; -import org.springframework.data.mongodb.core.mapping.DBRef; +import lombok.Getter; +import lombok.NoArgsConstructor; +import org.springframework.data.mongodb.core.mapping.Document; import org.springframework.data.mongodb.core.mapping.DocumentReference; -import java.awt.print.Book; +import java.util.ArrayList; import java.util.List; +@Document +@Getter +@NoArgsConstructor public class PartyChattingRoom extends ChattingRoom{ private String title; @@ -13,18 +18,34 @@ public class PartyChattingRoom extends ChattingRoom{ //TODO:채팅과 일대다 연관관계 테스트 중 // @DBRef // private List chattings; -// @DocumentReference -// private List chattings; + @DocumentReference // 일대다 + private List chattings = new ArrayList<>(); + +// @DocumentReference // 일대다 + private List participants = new ArrayList<>(); + +// private String accountNumber; +// private String bank; +// private String category; +// private boolean isFinish; +// private Integer maxMatching; public PartyChattingRoom(String title) { super(); this.title = title; } -// public PartyChattingRoom(String title, List chattings) { -// this.title = title; -// this.chattings = chattings; -// } + public PartyChattingRoom(String title, List chattings) { + super(); + this.title = title; + this.chattings = chattings; + } + + public PartyChattingRoom(String title, List chattings, List participants) { + this.title = title; + this.chattings = chattings; + this.participants = participants; + } @Override public String toString() { @@ -35,6 +56,10 @@ public String toString() { '}'; } + public void changeParticipants(ParticipantInfo participantInfo){ + this.participants.add(participantInfo); + } + } diff --git a/src/main/java/shop/geeksasangchat/dto/chattingmember/PostParticipantInfoReq.java b/src/main/java/shop/geeksasangchat/dto/chattingmember/PostParticipantInfoReq.java new file mode 100644 index 0000000..b0a181b --- /dev/null +++ b/src/main/java/shop/geeksasangchat/dto/chattingmember/PostParticipantInfoReq.java @@ -0,0 +1,18 @@ +package shop.geeksasangchat.dto.chattingmember; + +import lombok.Getter; +import lombok.NoArgsConstructor; + +import javax.validation.constraints.NotEmpty; +import java.time.LocalDateTime; + +@NoArgsConstructor +@Getter +public class PostParticipantInfoReq { + @NotEmpty + private String chattingRoomId; + + private Boolean isRemittance; + @NotEmpty + private String nickName; +} diff --git a/src/main/java/shop/geeksasangchat/rabbitmq/PartyChattingQueue.java b/src/main/java/shop/geeksasangchat/rabbitmq/PartyChattingQueue.java index 753ebc2..3e1930a 100644 --- a/src/main/java/shop/geeksasangchat/rabbitmq/PartyChattingQueue.java +++ b/src/main/java/shop/geeksasangchat/rabbitmq/PartyChattingQueue.java @@ -18,7 +18,7 @@ public class PartyChattingQueue { private TopicExchange topicExchange; private RabbitTemplate rabbitTemplate; - static final String EXCHANGE_NAME = "chatting-room-exchange-test2"; + static final String EXCHANGE_NAME = "chatting-exchange-1234"; static final String QUEUE_NAME = "chatting-room-queue-test9"; static final String ROUTING_KEY = "chatting.test.room3.#"; // 라우팅 키, publishing 하는 방법을 결정. static final String FANOUT_EXCHANGE_NAME = "test1.fanout"; diff --git a/src/main/java/shop/geeksasangchat/repository/PartyChattingRoomRepository.java b/src/main/java/shop/geeksasangchat/repository/PartyChattingRoomRepository.java new file mode 100644 index 0000000..46abb59 --- /dev/null +++ b/src/main/java/shop/geeksasangchat/repository/PartyChattingRoomRepository.java @@ -0,0 +1,14 @@ +package shop.geeksasangchat.repository; + +import org.springframework.data.mongodb.repository.MongoRepository; +import org.springframework.data.mongodb.repository.Query; +import shop.geeksasangchat.domain.ChattingRoom; +import shop.geeksasangchat.domain.PartyChattingRoom; + +import java.util.List; +import java.util.Optional; + +public interface PartyChattingRoomRepository extends MongoRepository { + @Query("{id:'?0'}") // 0번째 파라미터 조건 + Optional findByPartyChattingRoomId(String id); +} diff --git a/src/main/java/shop/geeksasangchat/service/PartyChattingService.java b/src/main/java/shop/geeksasangchat/service/PartyChattingService.java index c1beeab..932722a 100644 --- a/src/main/java/shop/geeksasangchat/service/PartyChattingService.java +++ b/src/main/java/shop/geeksasangchat/service/PartyChattingService.java @@ -10,13 +10,14 @@ import org.springframework.stereotype.Component; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; -import shop.geeksasangchat.domain.Chatting; -import shop.geeksasangchat.domain.ChattingRoom; -import shop.geeksasangchat.domain.PartyChattingRoom; +import shop.geeksasangchat.domain.*; import shop.geeksasangchat.rabbitmq.PartyChattingQueue; import shop.geeksasangchat.repository.ChattingRepository; import shop.geeksasangchat.repository.ChattingRoomRepository; +import shop.geeksasangchat.repository.PartyChattingRoomRepository; +import java.time.LocalDateTime; +import java.util.ArrayList; import java.util.List; import java.util.stream.Collectors; @@ -28,11 +29,14 @@ public class PartyChattingService { private final ChattingRoomRepository chattingRoomRepository; private final ChattingRepository chattingRepository; private final PartyChattingQueue partyChattingQueue; + private final PartyChattingRoomRepository partyChattingRoomRepository; @Transactional(readOnly = false) public String createChattingRoom(int userId, String title){ - PartyChattingRoom chattingRoom = new PartyChattingRoom(title); - PartyChattingRoom saveChattingRoom = chattingRoomRepository.save(chattingRoom); + List chattings = new ArrayList<>(); + List participants = new ArrayList<>(); + PartyChattingRoom chattingRoom = new PartyChattingRoom(title, chattings, participants); + PartyChattingRoom saveChattingRoom = partyChattingRoomRepository.save(chattingRoom); return saveChattingRoom.getId(); } @@ -44,6 +48,18 @@ public void createChatting(int userId, String chattingRoomId, String content, in } + @Transactional(readOnly = false) + public void joinPartyChattingRoom(String chattingRoomId, LocalDateTime enterTime, boolean isRemittance, String nickName){ + + PartyChattingRoom partyChattingRoom = partyChattingRoomRepository.findByPartyChattingRoomId(chattingRoomId) + .orElseThrow(() -> new NullPointerException()); + + // 파티 입장하는 멤버 정보 추가 + ParticipantInfo participantInfo = new ParticipantInfo(LocalDateTime.now(), isRemittance, nickName); + partyChattingRoom.changeParticipants(participantInfo); + partyChattingRoomRepository.save(partyChattingRoom); // MongoDB는 JPA처럼 변경감지가 안되어서 직접 저장해줘야 한다. + } + @Transactional(readOnly = true) public List findAllPartyChattingRooms(int userId){ // List partyChattingRoomList = chattingRoomRepository.findAll().stream()